From 49dd98e538bf581a53769e1cbfda82923e2c3a04 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 18 Jun 2026 17:59:02 +1200 Subject: [PATCH] refactor(transaction): inherit postgres startTransaction --- src/Database/Adapter/Postgres.php | 38 ------------------------------- tests/unit/SQLTransactionTest.php | 7 +++++- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index dbe41420c..586a4f141 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -31,44 +31,6 @@ class Postgres extends SQL { public const MAX_IDENTIFIER_NAME = 63; - /** - * @inheritDoc - */ - public function startTransaction(): bool - { - try { - if ($this->inTransaction === 0) { - try { - if ($this->getPDO()->inTransaction()) { - $this->getPDO()->rollBack(); - } else { - // If no active transaction, this has no effect. - $this->getPDO()->prepare('ROLLBACK')->execute(); - } - } catch (PDOException) { - // A pooled connection can report a transaction it no longer - // holds after a reconnect (e.g. Swoole PDOProxy keeps its own - // counter), making this cleanup rollback throw. It is best - // effort; swallow it and begin a fresh transaction below. - } - - $result = $this->getPDO()->beginTransaction(); - } else { - $this->getPDO()->exec('SAVEPOINT transaction' . $this->inTransaction); - $result = true; - } - } catch (PDOException $e) { - throw new TransactionException('Failed to start transaction: ' . $e->getMessage(), $e->getCode(), $e); - } - - if (!$result) { - throw new TransactionException('Failed to start transaction'); - } - - $this->inTransaction++; - - return $result; - } /** * @inheritDoc diff --git a/tests/unit/SQLTransactionTest.php b/tests/unit/SQLTransactionTest.php index 6fdfe9f03..fc4f5667f 100644 --- a/tests/unit/SQLTransactionTest.php +++ b/tests/unit/SQLTransactionTest.php @@ -4,11 +4,13 @@ use PDOException; use PHPUnit\Framework\TestCase; +use ReflectionMethod; use Utopia\Database\Adapter\MySQL; use Utopia\Database\Adapter\Postgres; +use Utopia\Database\Adapter\SQL; use Utopia\Database\Exception\Transaction as TransactionException; -class SQLTransactionTest extends TestCase +final class SQLTransactionTest extends TestCase { /** * A pooled connection (e.g. Swoole PDOProxy) can keep its own transaction @@ -61,6 +63,9 @@ public function testStartTransactionDoesNotMaskBeginFailureAfterDesyncedRollback public function testPostgresStartTransactionRecoversFromDesyncedRollback(): void { + $method = new ReflectionMethod(Postgres::class, 'startTransaction'); + $this->assertSame(SQL::class, $method->getDeclaringClass()->getName()); + $pdo = $this->getMockBuilder(\PDO::class) ->disableOriginalConstructor() ->getMock();