dmaicher/doctrine-test-bundle

Using PDO results in error

wnnawalaniec opened this issue · 7 comments

Not sure if bug, missing docs and this was expected but this bundle doesn't work with PDO, as PDO doesn't allow for nested transactions. Calling beginTransaction multiple times on same connection will result in exception. I created new Symfony 7 project, installed Doctrine bundle, Behat and this and in default config it won't work.

This happens because when StaticDriver connects for the first time it already starts new transaction, and then when test case begins in reaction to Behat event, BehatListener tries to begin another transaction.

nested transactions should be handled by Doctrine DBALs abstraction layer. It will use savepoints for that.

So yeah messing directly with PDO transactions will likely fail.

in reaction to Behat event, BehatListener tries to begin another transaction.

Can you point to the code that triggers this?

Ah you were talking about this?

in the test suite of this bundle it works fine. There shouldn't be any double transaction start.

Can you provide a reproducer for that issue?

Oh, I've found the issue but it took me some time, sorry. If you have DATABASE_URL like this:
DATABASE_URL="mysql://test:test@127.0.0.1:7000/test?serverVersion=16&charset=utf8"
All works fine. But, if you remove serverVersion it stops working:
DATABASE_URL="mysql://test:test@127.0.0.1:7000/test?charset=utf8"
I've created simple project with all bundles setup here https://github.com/wnnawalaniec/dama-test-issue, nothing special...

The reason for this is, that when setNestTransactionsWithSavepoints is called and platform is unknow doctrine will try to find out what server is used to check if nested transactions are supported, and to do this it connect to database. When it does, then the transaction begins due to StaticDriver starting it. Then when behat event is raised, this listener tries to begin yet another transaction which failes.

When we provide with serverVersion there is no connection made and $connections at StaticDriver is empty, therefor when this behat listener is begining transaction nothing happens. Then on first connection made in our code, StaticDriver starts new static connection and begin transaction only once.

Still not sure if it's this lib issue or doctrine stuff...

Hm interesting. Thanks for investigating @wnnawalaniec. I'm struggling to understand why this issue does not happen in the testsuite of the bundle however. There we also have a connection without server version and so it should also run this code to detect the platform.

I will try to dig into it a bit more.

Ok so I think this might have something todo with the fact that you are injecting the connection service into your context.

https://github.com/wnnawalaniec/dama-test-issue/blob/32bf6a1bb7b72651457c81ccfa6efdb16e034eb0/tests/Behat/DemoContext.php#L28

So the connection is initialized before we even run the hook that will do StaticDriver::beginTransaction()?

Does it work if you remove that injected connection service?

Yes it does

Ok so I don't see any way around this. The connection should not be used or initialized before that hook is run.

But you have a workaround for now by setting the server version.