diff --git a/CHANGELOG.md b/CHANGELOG.md index 452e8fcf..f03454a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ - add support for snapshot queries (#215) - deprecate Connection::getDatabaseContext() and move logic to UseMutations::getMutationExecutor() (#227) - add support for `Query\Builder::whereNotInUnnest(...)` (#225) -- `Query\Builder::whereIn` will now wrap values in `UNNEST` if the number of values exceeds the limit (950). (#) +- `Query\Builder::whereIn` will now wrap values in `UNNEST` if the number of values exceeds the limit (950). (#226) +- Commit options can now be set through config or through `Connection::setCommitOptions(...)` (#229) # v8.2.0 (2024-08-05) diff --git a/src/Concerns/ManagesTransactions.php b/src/Concerns/ManagesTransactions.php index bffbe3a0..d4eb61ba 100644 --- a/src/Concerns/ManagesTransactions.php +++ b/src/Concerns/ManagesTransactions.php @@ -39,6 +39,11 @@ trait ManagesTransactions protected ?int $maxAttempts = null; + /** + * @var array|null $commitOptions + */ + protected ?array $commitOptions = null; + /** * @inheritDoc * @template T @@ -158,7 +163,7 @@ protected function performSpannerCommit(): void { if ($this->transactions === 1 && $this->currentTransaction !== null) { $this->fireConnectionEvent('committing'); - $this->currentTransaction->commit(); + $this->currentTransaction->commit($this->getCommitOptions()); } [$levelBeingCommitted, $this->transactions] = [ @@ -263,4 +268,27 @@ public function setDefaultMaxTransactionAttempts(int $attempts): static $this->maxAttempts = $attempts; return $this; } + + /** + * @return array + */ + public function getCommitOptions(): array + { + if ($this->commitOptions !== null) { + return $this->commitOptions; + } + + $options = $this->getConfig('commit') ?? []; + assert(is_array($options)); + return $this->commitOptions = $options; + } + + /** + * @param array $options + * @return void + */ + public function setCommitOptions(array $options): void + { + $this->commitOptions = $options; + } } diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index deefc49d..7288a1b5 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -90,6 +90,37 @@ public function testCommit(): void Event::assertDispatchedTimes(TransactionRolledBack::class, 0); } + public function test_commit_with_options(): void + { + $conn = $this->getDefaultConnection(); + /** @var Transaction $tx */ + $tx = $conn->transaction(function (Connection $conn) { + return $conn->getCurrentTransaction(); + }); + $this->assertNotNull($tx); + $this->assertSame([], $tx->getCommitStats()); + $this->assertSame([], $conn->getCommitOptions()); + + $newOptions = ['returnCommitStats' => true]; + $conn->setCommitOptions($newOptions); + $this->assertSame($newOptions, $conn->getCommitOptions()); + + // True test for commit with options only works on the real Spanner. + if (getenv('SPANNER_EMULATOR_HOST')) { + $this->markTestSkipped( + 'Cannot fully verify commit options on emulator. ' . + 'Feature request for emulator: https://github.com/GoogleCloudPlatform/cloud-spanner-emulator/issues/184', + ); + } + + /** @var Transaction $tx */ + $tx = $conn->transaction(function (Connection $conn) { + $conn->table(self::TABLE_NAME_USER)->insert(['userId' => $this->generateUuid(), 'name' => 'test']); + return $conn->getCurrentTransaction(); + }); + $this->assertSame(['mutationCount' => 2], $tx->getCommitStats()); + } + public function testRollbackBeforeCommit(): void { Event::fake();