Closed nu111 closed 1 year ago
Interesting error :thinking: Can you show a stack trace for that exception?
[2023-02-04T13:53:30.152021+00:00] request.INFO: Matched route "app_user_list". {"route":"app_user_list","route_parameters":{"_route":"app_user_list","_controller":"App\\Controller\\UserController::list"},"request_uri":"http://localhost/api/v1.0/users/?limit=1","method":"GET"} []
[2023-02-04T13:53:30.178709+00:00] doctrine.INFO: Connecting with parameters array{"url":"<redacted>","dbname_suffix":"_test","driver":"mysqli","host":"<redacted>","port":3306,"user":"<redacted>","password":"<redacted>","driverOptions":[],"defaultTableOptions":[],"dama.keep_static":true,"dama.connection_name":"default","dbname":"<redacted>","charset":"utf8"} {"params":{"url":"<redacted>","dbname_suffix":"_test","driver":"mysqli","host":"<redacted>","port":3306,"user":"<redacted>","password":"<redacted>","driverOptions":[],"defaultTableOptions":[],"dama.keep_static":true,"dama.connection_name":"default","dbname":"<redacted>","charset":"utf8"}} []
[2023-02-04T13:53:30.182272+00:00] doctrine.DEBUG: Beginning transaction [] []
[2023-02-04T13:53:30.194672+00:00] request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\ConnectionException: "May not alter the nested transaction with savepoints behavior while a transaction is open." at /var/www/html/vendor/doctrine/dbal/src/ConnectionException.php line 39 {"exception":"[object] (Doctrine\\DBAL\\ConnectionException(code: 0): May not alter the nested transaction with savepoints behavior while a transaction is open. at /var/www/html/vendor/doctrine/dbal/src/ConnectionException.php:39)"} []
The full stack trace for the exception would be helpful
Here it is!
Testing App\Tests\CustomerTest
#0 /var/www/html/vendor/doctrine/dbal/src/Connection.php(1253): Doctrine\DBAL\ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction()
#1 /var/www/html/vendor/dama/doctrine-test-bundle/src/DAMA/DoctrineTestBundle/Doctrine/DBAL/StaticConnectionFactory.php(33): Doctrine\DBAL\Connection->setNestTransactionsWithSavepoints(true)
#2 /var/www/html/var/cache/test/Container48N8Zk2/getDoctrine_Dbal_DefaultConnectionService.php(22): DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticConnectionFactory->createConnection(Array, Object(Doctrine\DBAL\Configuration), Object(Symfony\Bridge\Doctrine\ContainerAwareEventManager), Array)
#3 /var/www/html/var/cache/test/Container48N8Zk2/App_KernelTestDebugContainer.php(237): Container48N8Zk2\getDoctrine_Dbal_DefaultConnectionService::do(Object(Container48N8Zk2\App_KernelTestDebugContainer), true)
#4 /var/www/html/var/cache/test/Container48N8Zk2/getDoctrine_Orm_DefaultEntityManagerService.php(27): Container48N8Zk2\App_KernelTestDebugContainer->load('getDoctrine_Dba...')
#5 /var/www/html/var/cache/test/Container48N8Zk2/App_KernelTestDebugContainer.php(237): Container48N8Zk2\getDoctrine_Orm_DefaultEntityManagerService::do(Object(Container48N8Zk2\App_KernelTestDebugContainer), true)
#6 /var/www/html/var/cache/test/Container48N8Zk2/getDoctrine_Orm_DefaultEntityManager_ValidatorLoaderService.php(24): Container48N8Zk2\App_KernelTestDebugContainer->load('getDoctrine_Orm...')
#7 /var/www/html/var/cache/test/Container48N8Zk2/App_KernelTestDebugContainer.php(237): Container48N8Zk2\getDoctrine_Orm_DefaultEntityManager_ValidatorLoaderService::do(Object(Container48N8Zk2\App_KernelTestDebugContainer), true)
#8 /var/www/html/var/cache/test/Container48N8Zk2/getValidator_BuilderService.php(33): Container48N8Zk2\App_KernelTestDebugContainer->load('getDoctrine_Orm...')
#9 /var/www/html/var/cache/test/Container48N8Zk2/App_KernelTestDebugContainer.php(237): Container48N8Zk2\getValidator_BuilderService::do(Object(Container48N8Zk2\App_KernelTestDebugContainer), true)
#10 /var/www/html/var/cache/test/Container48N8Zk2/getValidator_Mapping_CacheWarmerService.php(24): Container48N8Zk2\App_KernelTestDebugContainer->load('getValidator_Bu...')
#11 /var/www/html/var/cache/test/Container48N8Zk2/App_KernelTestDebugContainer.php(237): Container48N8Zk2\getValidator_Mapping_CacheWarmerService::do(Object(Container48N8Zk2\App_KernelTestDebugContainer), true)
#12 /var/www/html/var/cache/test/Container48N8Zk2/getCacheWarmerService.php(28): Container48N8Zk2\App_KernelTestDebugContainer->load('getValidator_Ma...')
#13 /var/www/html/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php(91): Container48N8Zk2\getCacheWarmerService::Container48N8Zk2\{closure}()
#14 /var/www/html/vendor/symfony/http-kernel/Kernel.php(585): Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp('/var/www/html/v...')
#15 /var/www/html/vendor/symfony/http-kernel/Kernel.php(787): Symfony\Component\HttpKernel\Kernel->initializeContainer()
#16 /var/www/html/vendor/symfony/http-kernel/Kernel.php(128): Symfony\Component\HttpKernel\Kernel->preBoot()
#17 /var/www/html/vendor/symfony/framework-bundle/Test/KernelTestCase.php(82): Symfony\Component\HttpKernel\Kernel->boot()
#18 /var/www/html/vendor/symfony/framework-bundle/Test/WebTestCase.php(46): Symfony\Bundle\FrameworkBundle\Test\KernelTestCase::bootKernel(Array)
#19 /var/www/html/tests/CustomerTest.php(78): Symfony\Bundle\FrameworkBundle\Test\WebTestCase::createClient()
#20 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(1608): App\Tests\CustomerTest->testOneFormat()
#21 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(1214): PHPUnit\Framework\TestCase->runTest()
#22 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\Framework\TestCase->runBare()
#23 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(964): PHPUnit\Framework\TestResult->run(Object(App\Tests\CustomerTest))
#24 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\Framework\TestCase->run(Object(PHPUnit\Framework\TestResult))
#25 /var/www/html/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(653): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#26 /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\Framework\TestSuite), Array, Array, true)
#27 /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\TextUI\Command->run(Array, true)
#28 /var/www/html/bin/phpunit(11): PHPUnit\TextUI\Command::main()
#29 {main}
Interesting. So it seems a transaction is already started before this is called:
Could you try to debug what starts the transaction on that connection instance?
@nu111 also it would be interesting if you could test https://github.com/dmaicher/doctrine-test-bundle/pull/232 (using composer req dama/doctrine-test-bundle "dev-remove_post_connect_event as 7.99" --dev
for example). There the whole flow changed a bit to prepare being compatible with Doctrine DBAL 4
@dmaicher with #232 composer req dama/doctrine-test-bundle "dev-remove_post_connect_event as 7.99" --dev
seems to work fine.
This is what mariadb general_log logged
230208 10:13:16 13 Connect <redacted> as anonymous on <redacted>
13 Query SET NAMES utf8
13 Query START TRANSACTION
13 Query SAVEPOINT DAMA_TEST
13 Prepare SELECT <redacted> FROM tblUser t0 WHERE t0.id = 1
13 Close stmt
13 Prepare SELECT <redacted> FROM tblUser t0 WHERE t0.email = ? LIMIT 2
13 Execute SELECT <redacted> FROM tblUser t0 WHERE t0.email = 'testing@example.com' LIMIT 2
13 Close stmt
13 Prepare SELECT <redacted> FROM tblUser t0 WHERE t0.email = ? LIMIT 2
13 Close stmt
230208 10:13:17 13 Prepare UPDATE tblUser SET <redacted> WHERE id = ?
13 Execute UPDATE tblUser SET <redacted> WHERE id = 1
13 Close stmt
13 Query ROLLBACK TO SAVEPOINT DAMA_TEST
13 Query ROLLBACK
13 Quit
Ok interesting. The release of the approach in https://github.com/dmaicher/doctrine-test-bundle/pull/232 will take a bit longer though as I want to be sure it works with the final release of DBAL 4.0.
Using the latest stable release of this bundle: Could you try to find out what starts the transaction before this happens?
Closing for now. Let me know whenever you have any more details on this issue.
Giving a follow-up to this issue. I get the same error, and to provide an answer to your previous question there is the callstack in my application.
1) Tests\Controller\UniqueDocument\RiskGravityControllerRouteTest::testIndex
Doctrine\DBAL\ConnectionException: May not alter the nested transaction with savepoints behavior while a transaction is open.
/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/ConnectionException.php:29
/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:1306
/home/chaxwell/public_html/symfony/project/vendor/dama/doctrine-test-bundle/src/DAMA/DoctrineTestBundle/Doctrine/DBAL/StaticConnectionFactory.php:33
/home/chaxwell/public_html/symfony/project/var/cache/test/ContainerGvzHmd9/App_KernelTestContainer.php:698
/home/chaxwell/public_html/symfony/project/var/cache/test/ContainerGvzHmd9/App_KernelTestContainer.php:731
/home/chaxwell/public_html/symfony/project/vendor/symfony/var-exporter/Internal/LazyObjectState.php:97
/home/chaxwell/public_html/symfony/project/vendor/symfony/var-exporter/LazyGhostTrait.php:176
/home/chaxwell/public_html/symfony/project/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:207
/home/chaxwell/public_html/symfony/project/vendor/doctrine/doctrine-bundle/CacheWarmer/DoctrineMetadataCacheWarmer.php:42
/home/chaxwell/public_html/symfony/project/vendor/symfony/framework-bundle/CacheWarmer/AbstractPhpFileCacheWarmer.php:46
/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php:96
/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/Kernel.php:526
/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/Kernel.php:709
/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/Kernel.php:122
/home/chaxwell/public_html/symfony/project/vendor/symfony/framework-bundle/Test/KernelTestCase.php:73
/home/chaxwell/public_html/symfony/project/vendor/symfony/framework-bundle/Test/WebTestCase.php:44
/home/chaxwell/public_html/symfony/project/tests/WebTestCase.php:28
/home/chaxwell/public_html/symfony/project/tests/Controller/UniqueDocument/RiskGravityControllerRouteTest.php:20
/home/chaxwell/public_html/symfony/project/vendor/phpunit/phpunit/src/Framework/TestResult.php:728
/home/chaxwell/public_html/symfony/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
/home/chaxwell/public_html/symfony/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
/home/chaxwell/public_html/symfony/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
/home/chaxwell/public_html/symfony/project/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:651
Here's t he stack for the first (and only) call to beginTransaction
Doctrine\DBAL\Connection->beginTransaction (/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:1343)
DAMA\DoctrineTestBundle\Doctrine\DBAL\PostConnectEventListener->postConnect (/home/chaxwell/public_html/symfony/project/vendor/dama/doctrine-test-bundle/src/DAMA/DoctrineTestBundle/Doctrine/DBAL/PostConnectEventListener.php:26)
Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent (/home/chaxwell/public_html/symfony/project/vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:63)
Doctrine\DBAL\Connection->connect (/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:393)
Doctrine\DBAL\Connection->getDatabasePlatformVersion (/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:446)
Doctrine\DBAL\Connection->detectDatabasePlatform (/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:408)
Doctrine\DBAL\Connection->getDatabasePlatform (/home/chaxwell/public_html/symfony/project/vendor/doctrine/dbal/src/Connection.php:316)
Doctrine\Bundle\DoctrineBundle\ConnectionFactory->getDatabasePlatform (/home/chaxwell/public_html/symfony/project/vendor/doctrine/doctrine-bundle/ConnectionFactory.php:131)
Doctrine\Bundle\DoctrineBundle\ConnectionFactory->createConnection (/home/chaxwell/public_html/symfony/project/vendor/doctrine/doctrine-bundle/ConnectionFactory.php:109)
DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticConnectionFactory->createConnection (/home/chaxwell/public_html/symfony/project/vendor/dama/doctrine-test-bundle/src/DAMA/DoctrineTestBundle/Doctrine/DBAL/StaticConnectionFactory.php:25)
ContainerGvzHmd9\App_KernelTestContainer->getDoctrine_Dbal_DefaultConnectionService (/home/chaxwell/public_html/symfony/project/var/cache/test/ContainerGvzHmd9/App_KernelTestContainer.php:698)
ContainerGvzHmd9\App_KernelTestContainer->getDoctrine_Orm_DefaultEntityManagerService (/home/chaxwell/public_html/symfony/project/var/cache/test/ContainerGvzHmd9/App_KernelTestContainer.php:731)
Symfony\Component\VarExporter\Internal\LazyObjectState->initialize (/home/chaxwell/public_html/symfony/project/vendor/symfony/var-exporter/Internal/LazyObjectState.php:97)
ContainerGvzHmd9\EntityManagerGhost1396729->__get (/home/chaxwell/public_html/symfony/project/vendor/symfony/var-exporter/LazyGhostTrait.php:176)
Doctrine\ORM\EntityManager->getMetadataFactory (/home/chaxwell/public_html/symfony/project/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:207)
Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer->doWarmUp (/home/chaxwell/public_html/symfony/project/vendor/doctrine/doctrine-bundle/CacheWarmer/DoctrineMetadataCacheWarmer.php:42)
Symfony\Bundle\FrameworkBundle\CacheWarmer\AbstractPhpFileCacheWarmer->warmUp (/home/chaxwell/public_html/symfony/project/vendor/symfony/framework-bundle/CacheWarmer/AbstractPhpFileCacheWarmer.php:46)
Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp (/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php:96)
Symfony\Component\HttpKernel\Kernel->initializeContainer (/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/Kernel.php:526)
Symfony\Component\HttpKernel\Kernel->preBoot (/home/chaxwell/public_html/symfony/project/vendor/symfony/http-kernel/Kernel.php:709)
I'm totally not an expert but I have tried to fast-fix this problem by simply moving the call of $connection->setNestTransactionsWithSavepoints(true);
before the transaction begins.
From here :
<?php
namespace DAMA\DoctrineTestBundle\Doctrine\DBAL;
use Doctrine\Bundle\DoctrineBundle\ConnectionFactory;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
class StaticConnectionFactory extends ConnectionFactory
{
/**
* @var ConnectionFactory
*/
private $decoratedFactory;
public function __construct(ConnectionFactory $decoratedFactory)
{
parent::__construct([]);
$this->decoratedFactory = $decoratedFactory;
}
public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = []): Connection
{
$connection = $this->decoratedFactory->createConnection($params, $config, $eventManager, $mappingTypes);
if (!StaticDriver::isKeepStaticConnections() || !isset($params['dama.keep_static']) || !$params['dama.keep_static']) {
return $connection;
}
- // Make sure we use savepoints to be able to easily roll-back nested transactions
- if ($connection->getDriver()->getDatabasePlatform()->supportsSavepoints()) {
- $connection->setNestTransactionsWithSavepoints(true);
- }
-
return $connection;
}
}
To here :
<?php
namespace DAMA\DoctrineTestBundle\Doctrine\DBAL;
use Doctrine\DBAL\Event\ConnectionEventArgs;
class PostConnectEventListener
{
public function postConnect(ConnectionEventArgs $args): void
{
// can be disabled at runtime
if (!StaticDriver::isKeepStaticConnections()) {
return;
}
// The underlying connection already has a transaction started.
// We start a transaction on the connection as well
// so the internal state ($_transactionNestingLevel) is in sync with the underlying connection.
+ $connection = $args->getConnection();
+
+ // Make sure we use savepoints to be able to easily roll-back nested transactions
+ if ($connection->getDriver()->getDatabasePlatform()->supportsSavepoints()) {
+ $connection->setNestTransactionsWithSavepoints(true);
+ }
$args->getConnection()->beginTransaction();
}
}
It works back again but I guess it would not in all situations, no idea.
I hope this helps :)
@Chaxwell thanks for the details!
Could you do me a favor and test https://github.com/dmaicher/doctrine-test-bundle/pull/232 ?
By running composer req --dev dama/doctrine-test-bundle "dev-remove_post_connect_event as 8.0"
for example
For supporting Doctrine DBAL 4 I need to change the approach quite a bit and I believe this will also solve this issue.
Seems like it's working just fine :)
$ XDEBUG_MODE=off symfony php ./vendor/symfony/phpunit-bridge/bin/simple-phpunit.php --filter RiskGravityControllerRouteTest
Debug mode: off
Clearing the cache... Cache cleared !
PHPUnit 9.6.6 by Sebastian Bergmann and contributors.
Testing
....... 7 / 7 (100%)
Time: 00:19.555, Memory: 259.00 MB
OK (7 tests, 23 assertions)
Remaining indirect deprecation notices (62)
Done in 20.02s.
Data is rolledback as expected.
I will test with my whole suite and see if it's still working as expected.
@Chaxwell nice. Let me know if it works fine with the whole testsuite. On my projects everything works as expected.
I would then merge #232 and probably tag a new v8.0.0-BETA1
release to collect some more feedback
@Chaxwell did you have a chance to test this with your whole testsuite? :blush:
Hi, I am on Symfony 5.4. I have followed the instructions to enable this bundle. During the installation process I allowed the recipe to run.
When I run my tests I get this error:
Any idea on what I am missing?