mirror of
https://github.com/dg/dibi.git
synced 2025-08-05 05:37:39 +02:00
Connection::transtaction() call can be nested
This commit is contained in:
committed by
David Grudl
parent
877dffd460
commit
b00e556289
@@ -40,6 +40,8 @@ class Connection implements IConnection
|
|||||||
/** @var HashMap Substitutes for identifiers */
|
/** @var HashMap Substitutes for identifiers */
|
||||||
private $substitutes;
|
private $substitutes;
|
||||||
|
|
||||||
|
private $transactionDepth = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection options: (see driver-specific options too)
|
* Connection options: (see driver-specific options too)
|
||||||
@@ -407,14 +409,26 @@ class Connection implements IConnection
|
|||||||
*/
|
*/
|
||||||
public function transaction(callable $callback)
|
public function transaction(callable $callback)
|
||||||
{
|
{
|
||||||
$this->begin();
|
if ($this->transactionDepth === 0) {
|
||||||
|
$this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->transactionDepth++;
|
||||||
try {
|
try {
|
||||||
$res = $callback($this);
|
$res = $callback($this);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->rollback();
|
$this->transactionDepth--;
|
||||||
|
if ($this->transactionDepth === 0) {
|
||||||
|
$this->rollback();
|
||||||
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
$this->commit();
|
|
||||||
|
$this->transactionDepth--;
|
||||||
|
if ($this->transactionDepth === 0) {
|
||||||
|
$this->commit();
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -73,3 +73,38 @@ test('transaction() success', function () use ($conn) {
|
|||||||
});
|
});
|
||||||
Assert::same(5, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle());
|
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());
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user