Description
Bug Report
Q | A |
---|---|
BC Break | no |
Version | 2.10.1 |
Summary
In case PDO::commit
returns false
, no exception is thrown, failures are not handled in any case.
This could happen, for example, if deadlock is received when using Galera cluster.
Current behaviour
Doctrine\DBAL\Connection
returns false
, which is totally ignored in all the places where it's called from, including EntityManager
and even Connection
internal methods.
No exception is thrown.
How to reproduce
<?php
declare(strict_types=1);
class ConnectionTest extends \Mockery\Adapter\Phpunit\MockeryTestCase
{
public function testTransactionalWithCommitReturningFalse()
{
$connectionMock = \Mockery::mock(\Doctrine\DBAL\Driver\Connection::class);
$driverMock = \Mockery::mock(\Doctrine\DBAL\Driver::class);
$driverMock->expects('connect')->andReturn($connectionMock);
$connection = new \Doctrine\DBAL\Connection(
[],
$driverMock
);
$connectionMock->expects('beginTransaction');
$connectionMock->expects('exec')->with('SELECT 1')->andReturn(0);
$connectionMock->expects('commit')->andReturn(false);
$this->expectException(\Doctrine\DBAL\ConnectionException::class);
$connection->transactional(function() use ($connection) {
$connection->exec('SELECT 1');
});
}
}
In real-world, one would need:
- to set-up Galera cluster;
- update the same rows using several processes which connects to different Galera nodes.
This bug is really critical from the business side, as application responds with success code – everything seems to be working, but database changes are not really persisted. No errors are sent to the developers about such problems, too.
Expected behaviour
Provided test case should pass – commit
method should throw an exception in case commit
returns false
and not to just return false
where it's not handled by any code whatsoever.
The same, but possibly not so critical, behaviour should be applied for rollBack
method – PDO::rollBack
can also return false
.
Activity