Skip to content

feat: Add support for the Isolation Level value#8234

Merged
bshaffer merged 30 commits intomainfrom
snapshot-isolation
Oct 7, 2025
Merged

feat: Add support for the Isolation Level value#8234
bshaffer merged 30 commits intomainfrom
snapshot-isolation

Conversation

@Hectorhammett
Copy link
Copy Markdown
Collaborator

@Hectorhammett Hectorhammett commented Apr 15, 2025

b/388238239

Copy link
Copy Markdown
Contributor

@bshaffer bshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick first pass!

Comment thread Spanner/src/Connection/Grpc.php Outdated
Comment thread Spanner/src/Database.php Outdated
Comment thread Spanner/src/Instance.php Outdated
@bshaffer bshaffer marked this pull request as ready for review May 13, 2025 19:53
@bshaffer bshaffer requested review from a team May 13, 2025 19:53
Copy link
Copy Markdown
Contributor

@bshaffer bshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before we merge this we need to update this similarly to what we have in #7749, which outlines the methods which this affects and how isolationLevel can be supplied as a parameter

Comment thread Spanner/tests/Unit/DatabaseTest.php Outdated
Copy link
Copy Markdown
Contributor

@bshaffer bshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The System tests pass locally for me! I still need to update the comment with more information on where the option is passed in (similar to in #7749), and also ensure that all those cases contain tests

@bshaffer
Copy link
Copy Markdown
Contributor

Here are the ways this option can currently be used:

  • SpannerClient constructor
  • Database::execute
  • Database::runTransaction
  • Database::transaction
  • Operation::transaction
  • Transaction::commit

Supplying Isolation Level here will throw an exception:

  • Database::executePartitionedUpdate
  • Transaction::executeUpdate (when "type" is single-use)

Potential Issues identified

  • Database::runTransaction does not get the client option value of isolationLevel passed into Database
  • Transaction::commit does 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"

@Hectorhammett Hectorhammett requested a review from bshaffer July 31, 2025 20:50
Comment thread Spanner/src/Instance.php
Comment thread Spanner/src/Instance.php Outdated
Comment thread Spanner/src/Instance.php
Comment thread Spanner/src/Database.php Outdated
Comment thread Spanner/src/Transaction.php Outdated
Comment thread Spanner/src/TransactionConfigurationTrait.php
@bshaffer bshaffer added next release PRs to be included in the next release api: spanner Issues related to the Spanner API. labels Oct 2, 2025
@Hectorhammett Hectorhammett requested a review from bshaffer October 6, 2025 18:40
Copy link
Copy Markdown
Contributor

@bshaffer bshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, but I have just a few thoughts for additional testing:

  • SpannerClient constructor - do we have a test which verifies that when isolationLevel is set as a client option, it's sent in the requests?
  • Transaction::commit - I don't see any tests which verify this behavior
  • Transaction::executeUpdate throws exception for single use - I'd like to see a test cover this as well

Comment thread Spanner/src/Database.php Outdated
@bshaffer bshaffer merged commit eb0de93 into main Oct 7, 2025
31 checks passed
@bshaffer bshaffer deleted the snapshot-isolation branch October 7, 2025 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: spanner Issues related to the Spanner API. next release PRs to be included in the next release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants