Skip to content

Commit

Permalink
Connection::setNestTransactionsWithSavepoints() should not break lazy…
Browse files Browse the repository at this point in the history
… connection (#6362)

|      Q       |   A
|------------- | -----------
| Type         | bug
| Fixed issues | N/A

#### Summary

When calling `Connection::setNestTransactionsWithSavepoints()`, the
platform is fetched to check if savepoints are actually supported. This
is a problem because it might cause the connection to be opened.

I've removed the check which will postpone the exception to the first
time we attempt to create a savepoint.
  • Loading branch information
derrabus committed Apr 25, 2024
1 parent ad2fee0 commit b05e48a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
4 changes: 0 additions & 4 deletions src/Connection.php
Expand Up @@ -1317,10 +1317,6 @@ public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoint
throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
}

if (! $this->getDatabasePlatform()->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}

$this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints;
}

Expand Down
42 changes: 42 additions & 0 deletions tests/ConnectionTest.php
Expand Up @@ -2,12 +2,14 @@

namespace Doctrine\DBAL\Tests;

use BadMethodCallException;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\DriverManager;
Expand Down Expand Up @@ -81,6 +83,46 @@ public function testNoTransactionActiveByDefault(): void
self::assertFalse($this->connection->isTransactionActive());
}

public function testSetNestTransactionsWithSavepointsDoesNotConnect(): void
{
$this->expectNotToPerformAssertions();

$connection = new Connection(
[],
new class implements VersionAwarePlatformDriver {
/** {@inheritDoc} */
public function connect(array $params): DriverConnection
{
throw new BadMethodCallException('The connection must not be opened');
}

public function getDatabasePlatform(): AbstractPlatform
{
throw new BadMethodCallException('The connection must not be opened');
}

public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager
{
throw new BadMethodCallException('The connection must not be opened');
}

public function getExceptionConverter(): ExceptionConverter
{
throw new BadMethodCallException('The connection must not be opened');
}

/** {@inheritDoc} */
public function createDatabasePlatformForVersion($version): AbstractPlatform
{
throw new BadMethodCallException('The connection must not be opened');
}
},
new Configuration(),
);

$connection->setNestTransactionsWithSavepoints(true);
}

public function testCommitWithNoActiveTransactionThrowsException(): void
{
$this->expectException(ConnectionException::class);
Expand Down
12 changes: 0 additions & 12 deletions tests/Functional/ConnectionTest.php
Expand Up @@ -195,18 +195,6 @@ public function testTransactionIsInactiveAfterConnectionClose(): void
self::assertFalse($this->connection->isTransactionActive());
}

public function testSetNestedTransactionsThroughSavepointsNotSupportedThrowsException(): void
{
if ($this->connection->getDatabasePlatform()->supportsSavepoints()) {
self::markTestSkipped('This test requires the platform not to support savepoints.');
}

$this->expectException(ConnectionException::class);
$this->expectExceptionMessage('Savepoints are not supported by this driver.');

$this->connection->setNestTransactionsWithSavepoints(true);
}

public function testCreateSavepointsNotSupportedThrowsException(): void
{
if ($this->connection->getDatabasePlatform()->supportsSavepoints()) {
Expand Down

0 comments on commit b05e48a

Please sign in to comment.