feat: Add support for the Isolation Level value
b/388238239
Here are the ways this option can currently be used:
SpannerClientconstructorDatabase::executeDatabase::runTransactionDatabase::transactionOperation::transactionTransaction::commit
Supplying Isolation Level here will throw an exception:
Database::executePartitionedUpdateTransaction::executeUpdate(when "type" is single-use)
Potential Issues identified
Database::runTransactiondoes not get the client option value ofisolationLevelpassed intoDatabaseTransaction::commitdoes some strangeness with passing the options back and forth - track down what this means
SpannerClient constructor
Supplying the isolationLevel to the SpannerClient constructor will ensure the Isolation Level is passed down to the Instance and Database, and will be present in the following calls:
$spanner = new SpannerClient(['isolationLevel' => $isolationLevel]);
// TransactionOptions.begin.isolationLevel will be set to $isolationLevel
$spanner->instance->database->execute($sql);
// TransactionOptions.begin.isolationLevel will be set to $newIsolationLevel
$spanner->instance->database->execute($sql, ['isolationLevel' => $newIsolationLevel]);
Database::execute
$database->execute($sql, ['isolationLevel' => $isolationLevel]);
Database::runTransaction
// NOTE: This does NOT get the operation from the client option. This seems like a bug
$database->runTransaction($operation);
// This will create a
$database->runTransaction($operation, ['isolationLevel' => $isolationLevel]);
Database::transaction
$database->transaction(['isolationLevel' => $isolationLevel]);
Operation::transaction
Operations now take a isolationlevel option when creating a transaction. This is either passed to a BeginTransaction request, or passed to a Transaction object.
Transaction::commit
When the Transaction object receives an isolationlevel in the constructor, it's passed back to Operation::transaction. This requires more investigation
// calls `Operation::transaction` under the hood, which can potentially create a new Transaction
// Also calls `TransactionConfigurationTrait::transactionOptions`, which adds the `isolationLevel`
// @TODO: figure out why/how this works.
$transaction->commit($session, ['isolationLevel' => $isolationLevel]);
Database::executePartitionedUpdate
The following will throw an InvalidArgumentException:
$database->executePartitionedUpdate($sql, ['transactionOptions' => ['isolationLevel' => $isolationLevel]])
// Throws InvalidArgumentException with "Partitioned DML cannot be configured with an isolation level"
Transaction::executeUpdate
The following will throw an ValidationException:
$database->executePartitionedUpdate($sql, ['transactionOptions' => ['isolationLevel' => $isolationLevel]])
// Throws ValidationException with "Partitioned DML cannot be configured with an isolation level"