dmaicher / doctrine-test-bundle

Symfony bundle to isolate your app's doctrine database tests and improve the test performance
MIT License
1.08k stars 60 forks source link

Start new transaction only once #224

Closed alexndlm closed 2 years ago

alexndlm commented 2 years ago

If adding some doctrine.event_subscriber which injects current connection or other services which inject current connection, the \DAMA\DoctrineTestBundle\Doctrine\DBAL\PostConnectEventListener will be registered two or more times, and the connection will be wrapped into tow or more transactions.

dmaicher commented 2 years ago

I cannot reproduce this issue.

How does your Doctrine event subscriber look like in such a case? Which events does it subscribe to?

alexndlm commented 2 years ago

Please check this https://github.com/eonx-com/easy-monorepo/pull/1014/files#diff-c7c0a9a7f08907b45e1969008ce3112362929b9b7c14f5c0fba9b673ae952ef1

$persistingStore depend on connection, please see here https://github.com/eonx-com/easy-monorepo/blob/c95e2e05ad0ea8f5003ff0622351e33e3b8e42af/packages/EasyLock/src/Bridge/Symfony/DependencyInjection/Compiler/RegisterLockStoreServicePass.php#L31

dmaicher commented 2 years ago

I tested it with a listener like this on one of my apps

<?php

namespace App;

use Doctrine\Common\EventSubscriber;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Events;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag(name: 'doctrine.event_subscriber')]
class TestListener implements EventSubscriber
{
    public function __construct(private Connection $connection)
    {
    }

    public function getSubscribedEvents()
    {
        return [Events::postConnect];
    }

    public function postConnect(): void
    {
        $this->connection->executeQuery('SELECT 1');
    }
}

and this plays nicely with this bundle and the PostConnectEventListener. I fail to understand how it can be registered multiple times.

Could you create a minimal reproducer for this? Maybe based on the Symfony demo?

alexndlm commented 2 years ago

Would you please add some debug echo to \DAMA\DoctrineTestBundle\Doctrine\DBAL\PostConnectEventListener::postConnect to see that it will be executed two times instead one.

dmaicher commented 2 years ago

I tried

        // 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.
        $args->getConnection()->beginTransaction();

        var_dump("here!", spl_object_hash($args->getConnection()));

and this is never executed for the same connection more than once for me.

alexndlm commented 2 years ago

What Symfony version do you have?

alexndlm commented 2 years ago

As remember this bug appears with Symfony >= 6.0

dmaicher commented 2 years ago

I'm using Symfony 5.4.

Could you create a minimal reproducer for this? Maybe based on the Symfony demo?

Then I will gladly take a look.

alexndlm commented 2 years ago

I noticed that I had an old version of the bundle.

After the update everything is ok.

Thanks.