1
0
mirror of https://github.com/dg/dibi.git synced 2025-02-22 01:48:05 +01:00

Connection::transtaction() call can be nested

This commit is contained in:
Miloslav Hůla 2021-04-04 22:35:32 +02:00 committed by David Grudl
parent 877dffd460
commit b00e556289
2 changed files with 52 additions and 3 deletions

View File

@ -40,6 +40,8 @@ class Connection implements IConnection
/** @var HashMap Substitutes for identifiers */
private $substitutes;
private $transactionDepth = 0;
/**
* Connection options: (see driver-specific options too)
@ -407,14 +409,26 @@ class Connection implements IConnection
*/
public function transaction(callable $callback)
{
$this->begin();
if ($this->transactionDepth === 0) {
$this->begin();
}
$this->transactionDepth++;
try {
$res = $callback($this);
} catch (\Throwable $e) {
$this->rollback();
$this->transactionDepth--;
if ($this->transactionDepth === 0) {
$this->rollback();
}
throw $e;
}
$this->commit();
$this->transactionDepth--;
if ($this->transactionDepth === 0) {
$this->commit();
}
return $res;
}

View File

@ -73,3 +73,38 @@ test('transaction() success', function () use ($conn) {
});
Assert::same(5, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle());
});
test('nested transaction() call fail', function () use ($conn) {
Assert::exception(function () use ($conn) {
$conn->transaction(function (Dibi\Connection $connection) {
$connection->query('INSERT INTO [products]', [
'title' => 'Test product',
]);
$connection->transaction(function (Dibi\Connection $connection2) {
$connection2->query('INSERT INTO [products]', [
'title' => 'Test product',
]);
throw new Exception('my exception');
});
});
}, \Throwable::class, 'my exception');
Assert::same(5, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle());
});
test('nested transaction() call success', function () use ($conn) {
$conn->transaction(function (Dibi\Connection $connection) {
$connection->query('INSERT INTO [products]', [
'title' => 'Test product',
]);
$connection->transaction(function (Dibi\Connection $connection2) {
$connection2->query('INSERT INTO [products]', [
'title' => 'Test product',
]);
});
});
Assert::same(7, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle());
});