8888class Database
8989{
9090 use ApiHelperTrait;
91- use TransactionConfigurationTrait;
9291 use RequestTrait;
9392
9493 public const CONTEXT_READ = 'r ' ;
@@ -128,6 +127,7 @@ class Database
128127 private CacheItemPoolInterface $ cacheItemPool ;
129128 private array $ info ;
130129 private int $ isolationLevel ;
130+ private TransactionOptionsBuilder $ transactionOptionsBuilder ;
131131
132132 /**
133133 * Create an object representing a Database.
@@ -185,6 +185,7 @@ public function __construct(
185185 );
186186
187187 $ this ->optionsValidator = new OptionsValidator ($ serializer );
188+ $ this ->transactionOptionsBuilder = new TransactionOptionsBuilder ();
188189 $ this ->directedReadOptions = $ instance ->directedReadOptions ();
189190 }
190191
@@ -747,25 +748,13 @@ public function snapshot(array $options = []): TransactionalReadInterface
747748 throw new BadMethodCallException ('Nested transactions are not supported by this client. ' );
748749 }
749750
750- $ options += [
751- 'singleUse ' => false
751+ $ snapshotOptions = [
752+ 'singleUse ' => $ options ['singleUse ' ] ?? false ,
753+ 'transactionOptions ' => $ this ->transactionOptionsBuilder
754+ ->configureReadOnlyTransactionOptions ($ options ),
752755 ];
753756
754- $ options ['transactionOptions ' ] = $ this ->configureReadOnlyTransactionOptions ($ options );
755-
756- // For backwards compatibility - remove all PBReadOnly fields
757- // This was previously being done in configureReadOnlyTransactionOptions
758- // @TODO: clean this up
759- unset(
760- $ options ['returnReadTimestamp ' ],
761- $ options ['strong ' ],
762- $ options ['readTimestamp ' ],
763- $ options ['exactStaleness ' ],
764- $ options ['minReadTimestamp ' ],
765- $ options ['maxStaleness ' ],
766- );
767-
768- return $ this ->operation ->snapshot ($ this ->session , $ options );
757+ return $ this ->operation ->snapshot ($ this ->session , $ snapshotOptions );
769758 }
770759
771760 /**
@@ -814,9 +803,11 @@ public function transaction(array $options = []): Transaction
814803 }
815804
816805 // Configure readWrite options here. Any nested options for readWrite should be added to this call
817- $ options ['transactionOptions ' ] = $ this ->configureReadWriteTransactionOptions (
818- ($ options ['transactionOptions ' ] ?? []) + ['isolationLevel ' => $ this ->isolationLevel ]
819- );
806+ $ txnOptions = $ options ['transactionOptions ' ] ?? [];
807+ $ options ['transactionOptions ' ] = $ this ->transactionOptionsBuilder
808+ ->configureReadWriteTransactionOptions ($ txnOptions + [
809+ 'isolationLevel ' => $ this ->isolationLevel
810+ ]);
820811
821812 return $ this ->operation ->transaction ($ this ->session , $ options );
822813 }
@@ -920,10 +911,11 @@ public function runTransaction(callable $operation, array $options = []): mixed
920911 : $ retrySettings ['maxRetries ' ];
921912
922913 // Configure necessary readWrite nested and base options
923- $ transactionOptions = $ options ['transactionOptions ' ] ?? [];
924- $ options ['transactionOptions ' ] = $ this ->configureReadWriteTransactionOptions (
925- $ transactionOptions + ['isolationLevel ' => $ this ->isolationLevel ]
926- );
914+ $ txnOptions = $ options ['transactionOptions ' ] ?? [];
915+ $ options ['transactionOptions ' ] = $ this ->transactionOptionsBuilder
916+ ->configureReadWriteTransactionOptions ($ txnOptions + [
917+ 'isolationLevel ' => $ this ->isolationLevel
918+ ]);
927919
928920 $ attempt = 0 ;
929921 $ startTransactionFn = function ($ options ) use (&$ attempt ) {
@@ -1666,28 +1658,23 @@ public function delete(string $table, KeySet $keySet, array $options = []): Time
16661658 */
16671659 public function execute ($ sql , array $ options = []): Result
16681660 {
1669- unset($ options ['requestOptions ' ]['transactionTag ' ]);
1670- $ session = $ this ->pluck ('session ' , $ options , false )
1671- ?: $ this ->session ;
1672-
1673- list (
1674- $ options ['transaction ' ],
1675- $ options ['transactionContext ' ]
1676- ) = $ this ->transactionSelector ($ options );
1677-
16781661 if (isset ($ options ['transaction ' ]['readWrite ' ])) {
16791662 $ options ['transaction ' ]['begin ' ]['isolationLevel ' ] ??= $ this ->isolationLevel ;
16801663 }
16811664
1682- $ options ['directedReadOptions ' ] = $ this ->configureDirectedReadOptions (
1683- $ options ,
1684- $ this ->directedReadOptions
1665+ [$ txnOptions , $ txnContext ] = $ this ->transactionOptionsBuilder ->transactionSelector ($ options );
1666+ $ directedReadOptions = $ this ->transactionOptionsBuilder ->configureDirectedReadOptions (
1667+ ['transaction ' => $ txnOptions ] + $ options ,
1668+ $ this ->directedReadOptions ,
16851669 );
16861670
1687- // Unset the internal flag.
1688- unset($ options ['singleUse ' ]);
1689- return $ this ->operation ->execute ($ session , $ sql , $ options + [
1690- 'route-to-leader ' => $ options ['transactionContext ' ] === Database::CONTEXT_READWRITE
1671+ $ session = $ options ['session ' ] ?? $ this ->session ;
1672+ $ executeOptions = $ this ->pluckArray (['parameters ' , 'types ' ], $ options );
1673+ return $ this ->operation ->execute ($ session , $ sql , $ executeOptions + [
1674+ 'transaction ' => $ txnOptions ,
1675+ 'transactionContext ' => $ txnContext ,
1676+ 'directedReadOptions ' => $ directedReadOptions ,
1677+ 'route-to-leader ' => $ txnContext === Database::CONTEXT_READWRITE
16911678 ]);
16921679 }
16931680
@@ -1903,8 +1890,6 @@ public function batchWrite(array $mutationGroups, array $options = []): Generato
19031890 */
19041891 public function executePartitionedUpdate ($ statement , array $ options = []): int
19051892 {
1906- unset($ options ['requestOptions ' ]['transactionTag ' ]);
1907-
19081893 if (isset ($ options ['transactionOptions ' ]['isolationLevel ' ])) {
19091894 throw new ValidationException ('Partitioned DML cannot be configured with an isolation level ' );
19101895 }
@@ -1915,11 +1900,13 @@ public function executePartitionedUpdate($statement, array $options = []): int
19151900 ]
19161901 ];
19171902
1903+ unset($ options ['requestOptions ' ]['transactionTag ' ]);
19181904 if (isset ($ options ['transactionOptions ' ]['excludeTxnFromChangeStreams ' ])) {
19191905 $ beginTransactionOptions ['transactionOptions ' ]['excludeTxnFromChangeStreams ' ] =
19201906 $ options ['transactionOptions ' ]['excludeTxnFromChangeStreams ' ];
19211907 unset($ options ['transactionOptions ' ]);
19221908 }
1909+
19231910 $ transaction = $ this ->operation ->transaction ($ this ->session , $ beginTransactionOptions );
19241911
19251912 return $ this ->operation ->executeUpdate ($ this ->session , $ transaction , $ statement , [
@@ -2053,21 +2040,23 @@ public function executePartitionedUpdate($statement, array $options = []): int
20532040 */
20542041 public function read ($ table , KeySet $ keySet , array $ columns , array $ options = []): Result
20552042 {
2056- unset($ options ['requestOptions ' ]['transactionTag ' ]);
2057-
2058- list ($ transactionOptions , $ context ) = $ this ->transactionSelector ($ options );
2059- $ options ['transaction ' ] = $ transactionOptions ;
2060- $ options ['transactionContext ' ] = $ context ;
2043+ [$ txnOptions , $ txnContext ] = $ this ->transactionOptionsBuilder ->transactionSelector ($ options );
20612044
2062- $ options [ ' directedReadOptions ' ] = $ this ->configureDirectedReadOptions (
2063- $ options ,
2064- $ this -> directedReadOptions
2045+ $ readOptions = $ this ->pluckArray (
2046+ [ ' index ' , ' limit ' , ' orderBy ' , ' lockHint ' , ' directedReadOptions ' ] ,
2047+ $ options
20652048 );
2049+ $ readOptions += [
2050+ 'transactionContext ' => $ txnContext ,
2051+ 'directedReadOptions ' => $ this ->transactionOptionsBuilder ->configureDirectedReadOptions (
2052+ ['transaction ' => $ txnOptions ] + $ readOptions ,
2053+ $ this ->directedReadOptions
2054+ ),
2055+ 'transaction ' => $ txnOptions ,
2056+ ];
20662057
2067- // Unset the internal flag.
2068- unset($ options ['singleUse ' ]);
2069- return $ this ->operation ->read ($ this ->session , $ table , $ keySet , $ columns , $ options + [
2070- 'route-to-leader ' => $ context === Database::CONTEXT_READ
2058+ return $ this ->operation ->read ($ this ->session , $ table , $ keySet , $ columns , $ readOptions + [
2059+ 'route-to-leader ' => $ txnContext === Database::CONTEXT_READ
20712060 ]);
20722061 }
20732062
@@ -2146,7 +2135,7 @@ public function createDatabaseFromBackup($name, $backup, array $options = []): L
21462135 {
21472136 $ options += [
21482137 'parent ' => $ this ->instance ->name (),
2149- 'databaseId ' => $ this ->databaseIdOnly ($ name ),
2138+ 'databaseId ' => $ this ->databaseId ($ name ),
21502139 'backup ' => $ backup instanceof Backup ? $ backup ->name () : $ backup
21512140 ];
21522141 /**
@@ -2368,7 +2357,7 @@ private function getCreateDbStatement(int $dialect): string
23682357 * @param string $name The database name or id.
23692358 * @return string
23702359 */
2371- private function databaseIdOnly (string $ name ): string
2360+ private function databaseId (string $ name ): string
23722361 {
23732362 try {
23742363 return DatabaseAdminClient::parseName ($ name )['database ' ];
0 commit comments