Skip to content

Commit b6137c8

Browse files
committed
Add guard clause
It maybe happen that the SQL COMMIT statement is successful, but then something goes wrong. In that kind of case, you do not want to attempt a rollback. This was implemented in UnitOfWork::commit(), but for some reason not in the similar EntityManager methods.
1 parent 51be1b1 commit b6137c8

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/EntityManager.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ public function transactional($func)
259259
} finally {
260260
if (! $successful) {
261261
$this->close();
262-
$this->conn->rollBack();
262+
if ($this->conn->isTransactionActive()) {
263+
$this->conn->rollBack();
264+
}
263265
}
264266
}
265267
}
@@ -285,7 +287,9 @@ public function wrapInTransaction(callable $func)
285287
} finally {
286288
if (! $successful) {
287289
$this->close();
288-
$this->conn->rollBack();
290+
if ($this->conn->isTransactionActive()) {
291+
$this->conn->rollBack();
292+
}
289293
}
290294
}
291295
}

tests/Tests/ORM/EntityManagerTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Exception;
3030
use Generator;
3131
use InvalidArgumentException;
32+
use PHPUnit\Framework\Assert;
3233
use stdClass;
3334
use TypeError;
3435

@@ -409,6 +410,33 @@ public function rollBack(): bool
409410
}
410411
}
411412

413+
/** @dataProvider entityManagerMethodNames */
414+
public function testItDoesNotAttemptToRollbackIfNoTransactionIsActive(string $methodName): void
415+
{
416+
$entityManager = new EntityManagerMock(
417+
new class extends ConnectionMock {
418+
public function commit(): bool
419+
{
420+
throw new Exception('Commit exception that happens after doing the actual commit');
421+
}
422+
423+
public function rollBack(): bool
424+
{
425+
Assert::fail('Should not attempt to rollback if no transaction is active');
426+
}
427+
428+
public function isTransactionActive(): bool
429+
{
430+
return false;
431+
}
432+
}
433+
);
434+
435+
$this->expectExceptionMessage('Commit exception');
436+
$entityManager->$methodName(static function (): void {
437+
});
438+
}
439+
412440
/** @return Generator<string, array{string}> */
413441
public function entityManagerMethodNames(): Generator
414442
{

0 commit comments

Comments
 (0)