diff --git a/src/Dibi/Connection.php b/src/Dibi/Connection.php index 3e54a395..1088af4b 100644 --- a/src/Dibi/Connection.php +++ b/src/Dibi/Connection.php @@ -337,6 +337,10 @@ class Connection implements IConnection */ public function begin(string $savepoint = null): void { + if ($this->transactionDepth !== 0) { + throw new \LogicException(__METHOD__ . '() call is forbidden inside a transaction() callback'); + } + if (!$this->driver) { $this->connect(); } @@ -361,6 +365,10 @@ class Connection implements IConnection */ public function commit(string $savepoint = null): void { + if ($this->transactionDepth !== 0) { + throw new \LogicException(__METHOD__ . '() call is forbidden inside a transaction() callback'); + } + if (!$this->driver) { $this->connect(); } @@ -385,6 +393,10 @@ class Connection implements IConnection */ public function rollback(string $savepoint = null): void { + if ($this->transactionDepth !== 0) { + throw new \LogicException(__METHOD__ . '() call is forbidden inside a transaction() callback'); + } + if (!$this->driver) { $this->connect(); } diff --git a/tests/dibi/Connection.transactions.phpt b/tests/dibi/Connection.transactions.phpt index b24f8e0a..457007a1 100644 --- a/tests/dibi/Connection.transactions.phpt +++ b/tests/dibi/Connection.transactions.phpt @@ -108,3 +108,24 @@ test('nested transaction() call success', function () use ($conn) { }); Assert::same(7, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle()); }); + + +test('begin(), commit() & rollback() calls are forbidden in transaction()', function () use ($conn) { + Assert::exception(function () use ($conn) { + $conn->transaction(function (Dibi\Connection $connection) { + $connection->begin(); + }); + }, \LogicException::class, Dibi\Connection::class . '::begin() call is forbidden inside a transaction() callback'); + + Assert::exception(function () use ($conn) { + $conn->transaction(function (Dibi\Connection $connection) { + $connection->commit(); + }); + }, \LogicException::class, Dibi\Connection::class . '::commit() call is forbidden inside a transaction() callback'); + + Assert::exception(function () use ($conn) { + $conn->transaction(function (Dibi\Connection $connection) { + $connection->rollback(); + }); + }, \LogicException::class, Dibi\Connection::class . '::rollback() call is forbidden inside a transaction() callback'); +});