From 3bb5fddc80fd45026d6c37fed950ffe35e939bd8 Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Sun, 7 Jun 2026 20:31:33 +0200 Subject: [PATCH 1/3] feat: Add `transaction` method to manage closures within transactions --- src/Connection.php | 20 ++++++++++++++++++++ src/DoctrineConnectionInterface.php | 14 ++++++++++++++ src/MockConnection.php | 7 +++++++ 3 files changed, 41 insertions(+) diff --git a/src/Connection.php b/src/Connection.php index b29a5c74..c268bce5 100755 --- a/src/Connection.php +++ b/src/Connection.php @@ -25,12 +25,14 @@ use Artemeon\Database\Schema\Table; use Artemeon\Database\Schema\TableIndex; use BackedEnum; +use Closure; use Generator; use InvalidArgumentException; use Override; use Psr\Log\LoggerInterface; use RuntimeException; use Stringable; +use Throwable; /** * This class handles all traffic from and to the database and takes care of a correct tx-handling @@ -741,6 +743,24 @@ public function rollBack(): void $this->numberOfOpenTransactions--; } + #[Override] + public function transaction(Closure $callback): mixed + { + $this->beginTransaction(); + + try { + $callbackResult = $callback(); + } catch (Throwable $exception) { + $this->rollBack(); + + throw $exception; + } + + $this->commit(); + + return $callbackResult; + } + /** * @inheritDoc * @throws ConnectionException diff --git a/src/DoctrineConnectionInterface.php b/src/DoctrineConnectionInterface.php index c3c51934..662b7457 100644 --- a/src/DoctrineConnectionInterface.php +++ b/src/DoctrineConnectionInterface.php @@ -13,8 +13,10 @@ namespace Artemeon\Database; +use Closure; use Generator; use Stringable; +use Throwable; /** * Interface, which is compatible to the Doctrine DBAL Connection class @@ -128,4 +130,16 @@ public function commit(): void; * Rollback of the current transaction. */ public function rollBack(): void; + + /** + * Execute a Closure within a transaction. + * + * @template TReturn of mixed + * + * @param Closure():TReturn $callback + * + * @throws Throwable + * @return TReturn + */ + public function transaction(Closure $callback): mixed; } diff --git a/src/MockConnection.php b/src/MockConnection.php index e6b728e7..bf475364 100644 --- a/src/MockConnection.php +++ b/src/MockConnection.php @@ -18,6 +18,7 @@ use Artemeon\Database\Schema\Table; use Artemeon\Database\Schema\TableIndex; use BackedEnum; +use Closure; use Generator; use Override; @@ -221,6 +222,12 @@ public function transactionRollback(): void { } + #[Override] + public function transaction(Closure $callback): mixed + { + return $callback(); + } + #[Override] public function hasDriver(string $class): bool { From a8a01b8df2d0f494984bd995cfbb194723b6fdbd Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Mon, 8 Jun 2026 11:47:43 +0200 Subject: [PATCH 2/3] fix: Ensure `commit` is called only on successful transaction execution --- src/Connection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Connection.php b/src/Connection.php index c268bce5..b7dff9ec 100755 --- a/src/Connection.php +++ b/src/Connection.php @@ -750,14 +750,14 @@ public function transaction(Closure $callback): mixed try { $callbackResult = $callback(); + + $this->commit(); } catch (Throwable $exception) { $this->rollBack(); throw $exception; } - $this->commit(); - return $callbackResult; } From 5d24c80af317f7d837ff80847285cabb10fd6b80 Mon Sep 17 00:00:00 2001 From: Marc Reichel Date: Tue, 9 Jun 2026 13:08:10 +0200 Subject: [PATCH 3/3] refactor: Rename `transaction` method to `transactional` --- src/Connection.php | 2 +- src/DoctrineConnectionInterface.php | 2 +- src/MockConnection.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Connection.php b/src/Connection.php index b7dff9ec..be3472e6 100755 --- a/src/Connection.php +++ b/src/Connection.php @@ -744,7 +744,7 @@ public function rollBack(): void } #[Override] - public function transaction(Closure $callback): mixed + public function transactional(Closure $callback): mixed { $this->beginTransaction(); diff --git a/src/DoctrineConnectionInterface.php b/src/DoctrineConnectionInterface.php index 662b7457..bb175916 100644 --- a/src/DoctrineConnectionInterface.php +++ b/src/DoctrineConnectionInterface.php @@ -141,5 +141,5 @@ public function rollBack(): void; * @throws Throwable * @return TReturn */ - public function transaction(Closure $callback): mixed; + public function transactional(Closure $callback): mixed; } diff --git a/src/MockConnection.php b/src/MockConnection.php index bf475364..565579ee 100644 --- a/src/MockConnection.php +++ b/src/MockConnection.php @@ -223,7 +223,7 @@ public function transactionRollback(): void } #[Override] - public function transaction(Closure $callback): mixed + public function transactional(Closure $callback): mixed { return $callback(); }