@@ -286,10 +286,10 @@ public function query(array $command, ?string $db = null): stdClass|array|int
286
286
// Add transaction options from startTransaction
287
287
if (isset ($ this ->sessions [$ sessionId ]['transactionOptions ' ])) {
288
288
$ txnOpts = $ this ->sessions [$ sessionId ]['transactionOptions ' ];
289
- if (isset ($ txnOpts ['readConcern ' ])) {
289
+ if (isset ($ txnOpts ['readConcern ' ]) && ! isset ( $ command [ ' readConcern ' ]) ) {
290
290
$ command ['readConcern ' ] = $ txnOpts ['readConcern ' ];
291
291
}
292
- if (isset ($ txnOpts ['writeConcern ' ])) {
292
+ if (isset ($ txnOpts ['writeConcern ' ]) && ! isset ( $ command [ ' writeConcern ' ]) ) {
293
293
$ command ['writeConcern ' ] = $ txnOpts ['writeConcern ' ];
294
294
}
295
295
}
@@ -628,8 +628,8 @@ public function insert(string $collection, array $document, array $options = [])
628
628
$ command ['writeConcern ' ] = $ this ->createWriteConcern ($ options ['writeConcern ' ]);
629
629
}
630
630
631
- // Add read concern if provided with validation
632
- if (isset ($ options ['readConcern ' ])) {
631
+ // Add read concern if provided with validation (skip for non-first transaction operations)
632
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
633
633
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
634
634
}
635
635
@@ -706,8 +706,8 @@ public function insertMany(string $collection, array $documents, array $options
706
706
$ command ['writeConcern ' ] = $ this ->createWriteConcern ($ options ['writeConcern ' ]);
707
707
}
708
708
709
- // Add read concern if provided with validation
710
- if (isset ($ options ['readConcern ' ])) {
709
+ // Add read concern if provided with validation (skip for non-first transaction operations)
710
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
711
711
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
712
712
}
713
713
@@ -787,8 +787,8 @@ public function update(string $collection, array $where = [], array $updates = [
787
787
$ command ['writeConcern ' ] = $ this ->createWriteConcern ($ options ['writeConcern ' ]);
788
788
}
789
789
790
- // Add read concern if provided with validation
791
- if (isset ($ options ['readConcern ' ])) {
790
+ // Add read concern if provided with validation (skip for non-first transaction operations)
791
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
792
792
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
793
793
}
794
794
@@ -875,8 +875,8 @@ public function find(string $collection, array $filters = [], array $options = [
875
875
$ command ['session ' ] = $ options ['session ' ];
876
876
}
877
877
878
- // Add read concern if provided with validation
879
- if (isset ($ options ['readConcern ' ])) {
878
+ // Add read concern if provided with validation (skip for non-first transaction operations)
879
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
880
880
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
881
881
}
882
882
@@ -924,8 +924,8 @@ public function aggregate(string $collection, array $pipeline, array $options =
924
924
$ command ['session ' ] = $ options ['session ' ];
925
925
}
926
926
927
- // Add read concern if provided with validation
928
- if (isset ($ options ['readConcern ' ])) {
927
+ // Add read concern if provided with validation (skip for non-first transaction operations)
928
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
929
929
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
930
930
}
931
931
@@ -1032,8 +1032,8 @@ public function delete(string $collection, array $filters = [], int $limit = 1,
1032
1032
$ command ['writeConcern ' ] = $ this ->createWriteConcern ($ options ['writeConcern ' ]);
1033
1033
}
1034
1034
1035
- // Add read concern if provided with validation
1036
- if (isset ($ options ['readConcern ' ])) {
1035
+ // Add read concern if provided with validation (skip for non-first transaction operations)
1036
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
1037
1037
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
1038
1038
}
1039
1039
@@ -1076,8 +1076,8 @@ public function count(string $collection, array $filters, array $options): int
1076
1076
$ command ['session ' ] = $ options ['session ' ];
1077
1077
}
1078
1078
1079
- // Add read concern if provided with validation
1080
- if (isset ($ options ['readConcern ' ])) {
1079
+ // Add read concern if provided with validation (skip for non-first transaction operations)
1080
+ if (isset ($ options ['readConcern ' ]) && ! $ this -> shouldSkipReadConcern ( $ options ) ) {
1081
1081
$ command ['readConcern ' ] = $ this ->createReadConcern ($ options ['readConcern ' ]);
1082
1082
}
1083
1083
@@ -1196,6 +1196,9 @@ public function startTransaction(array $session, array $options = []): bool
1196
1196
$ sessionState ['state ' ] = self ::TRANSACTION_IN_PROGRESS ;
1197
1197
$ sessionState ['lastUse ' ] = time ();
1198
1198
1199
+ // Reset the firstOperationDone flag for the new transaction
1200
+ unset($ sessionState ['firstOperationDone ' ]);
1201
+
1199
1202
// Store transaction options for use with actual operations
1200
1203
$ sessionState ['transactionOptions ' ] = [];
1201
1204
@@ -1635,10 +1638,10 @@ public function isTransientTransactionError(Exception $exception): bool
1635
1638
];
1636
1639
1637
1640
return in_array ($ code , $ transientCodes ) ||
1638
- str_contains ($ message , self ::TRANSIENT_TRANSACTION_ERROR ) ||
1639
- str_contains ($ message , 'connection ' ) ||
1640
- str_contains ($ message , 'timeout ' ) ||
1641
- str_contains ($ message , 'network ' );
1641
+ str_contains ($ message , self ::TRANSIENT_TRANSACTION_ERROR ) ||
1642
+ str_contains ($ message , 'connection ' ) ||
1643
+ str_contains ($ message , 'timeout ' ) ||
1644
+ str_contains ($ message , 'network ' );
1642
1645
}
1643
1646
1644
1647
/**
@@ -1666,7 +1669,7 @@ public function isUnknownTransactionCommitResult(Exception $exception): bool
1666
1669
];
1667
1670
1668
1671
return in_array ($ code , $ unknownCommitCodes ) ||
1669
- str_contains ($ message , self ::UNKNOWN_TRANSACTION_COMMIT_RESULT );
1672
+ str_contains ($ message , self ::UNKNOWN_TRANSACTION_COMMIT_RESULT );
1670
1673
}
1671
1674
1672
1675
/**
@@ -1875,6 +1878,44 @@ public function createWriteConcern($writeConcern): array
1875
1878
throw new Exception ('Invalid write concern format ' );
1876
1879
}
1877
1880
1881
+ /**
1882
+ * Check if readConcern should be skipped for a transaction operation
1883
+ *
1884
+ * @param array $options The options array containing session
1885
+ * @return bool True if readConcern should be skipped
1886
+ */
1887
+ private function shouldSkipReadConcern (array $ options ): bool
1888
+ {
1889
+ if (!isset ($ options ['session ' ])) {
1890
+ return false ;
1891
+ }
1892
+
1893
+ $ sessionData = $ options ['session ' ];
1894
+
1895
+ // Use the same extraction logic as in query() method
1896
+ $ sessionId = null ;
1897
+ if (is_array ($ sessionData ) && isset ($ sessionData ['id ' ])) {
1898
+ $ rawId = $ sessionData ['id ' ]->id ?? null ;
1899
+ $ sessionId = $ rawId instanceof \MongoDB \BSON \Binary
1900
+ ? bin2hex ($ rawId ->getData ())
1901
+ : $ rawId ;
1902
+ } else {
1903
+ $ rawId = $ sessionData ->id ?? null ;
1904
+ $ sessionId = $ rawId instanceof \MongoDB \BSON \Binary
1905
+ ? bin2hex ($ rawId ->getData ())
1906
+ : $ rawId ;
1907
+ }
1908
+
1909
+ // If in transaction and not first operation, skip readConcern
1910
+ if ($ sessionId && isset ($ this ->sessions [$ sessionId ]) &&
1911
+ $ this ->sessions [$ sessionId ]['state ' ] === self ::TRANSACTION_IN_PROGRESS &&
1912
+ isset ($ this ->sessions [$ sessionId ]['firstOperationDone ' ])) {
1913
+ return true ;
1914
+ }
1915
+
1916
+ return false ;
1917
+ }
1918
+
1878
1919
/**
1879
1920
* Create a read concern object with validation.
1880
1921
*
0 commit comments