Skip to content

[Messenger] Fix Doctrine setup when using a migration #40055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 1, 2021

Conversation

fabpot
Copy link
Member

@fabpot fabpot commented Feb 1, 2021

Q A
Branch? 5.2
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #39928
License MIT
Doc PR n/a

#38136 fixed running messenger:setup-transports (issue reported in #37179), but it breaks usage with make:migration (reported in #39928) as code is already executed in a transaction.

This PR fixes both use cases.

@fabpot fabpot requested a review from sroze as a code owner February 1, 2021 14:38
@carsonbot carsonbot added this to the 5.2 milestone Feb 1, 2021
@fabpot fabpot merged commit 8f325f5 into symfony:5.2 Feb 1, 2021
@fabpot fabpot deleted the messenger-table-setup-fix branch February 1, 2021 15:16
@fabpot fabpot mentioned this pull request Feb 3, 2021
@burned42
Copy link
Contributor

burned42 commented Feb 8, 2021

Unfortunately this broke messenger:setup-transports again for me after updating to 5.2.3 with exactly the same error message like in the linked issues.

@alexdruhet
Copy link

Also unfortunately, since upgrading to 5.2.3 it's possible that this also broke doctrine:schema:create, I'm investigating from the message:

No active sql transaction: 7 ERROR: LOCK TABLE can only be used in transaction blocks' while executing DDL: LOCK TABLE messenger_messages;

@Nyholm
Copy link
Member

Nyholm commented Mar 2, 2021

The Messenger component have an event listener (Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber) that listens to "onSchemaCreateTable".
That event is fired when one execute doctrine:schema:create (and plenty of more situations). The event listener asks PostgressSqlConnection::getExtraSetupSqlForTable() for SQL to be executed. Since that SQL includes a LOCK TABLE, the SQL needs to be in a transaction.

The command doctrine:schema:create does not wrapp things in a transaction, hence, we need BEGIN in the SQL from PostgressSqlConnection::getExtraSetupSqlForTable().


From my testing with Postgress 11 and Postgress 13. It is fine to have BEGIN and COMMIT in a db migration. I don't experience this issues reported in #39928.

I've tested with AbstractMigration::isTransactional() to be true and false.

@Nyholm
Copy link
Member

Nyholm commented Mar 2, 2021

From my testing with Postgress 11 and Postgress 13. It is fine to have BEGIN and COMMIT in a db migration. I don't experience this issues reported in #39928.

The bug is only present in PHP 8. I was testing with PHP 7

fabpot added a commit that referenced this pull request Mar 4, 2021
This PR was squashed before being merged into the 5.2 branch.

Discussion
----------

[Messenger] Doctrine setup with migrations

| Q             | A
| ------------- | ---
| Branch?       | 5.2
| Bug fix?      | yes
| New feature?  |
| Deprecations? | no
| Tickets       | Fix #40130
| License       | MIT
| Doc PR        |

This PR reverts parts of #40055.

When running these commands, You do need to be in a transaction:
- `doctrine:schema:create`
- `messenger:setup-transports`
- `doctrine:migrations:diff` and `doctrine:migrations:migrate`

Commits
-------

3371e1c [Messenger] Doctrine setup with migrations
fabpot added a commit that referenced this pull request Mar 5, 2021
This PR was merged into the 5.2 branch.

Discussion
----------

[Messenger] Don't lock tables or start transactions

| Q             | A
| ------------- | ---
| Branch?       | 5.2
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       |
| License       | MIT
| Doc PR        |

I was so sure my PR #40336 fixed the doctrine-messenger issue once and for all. But it had a very silent bug..

This has been tricky to debug and find because the `PDO` behaves differently in PHP 7.4 compared to PHP 8.

| Scenario | Command | Is executed in transaction | Method that calls `PostgreSqlConnection::getTriggerSql()` |
| --| -- | -- | -- |
| A | `messenger:setup-transports` | No | `setup()`
| B| `doctrine:schema:create` | No | `getExtraSetupSqlForTable()`
| C | `doctrine:migration:diff` | Yes by default, but it can be configured | `getExtraSetupSqlForTable()`

PR #40055 fixed scenario C on PHP 8, but that also broke scenario B on PHP 7.4 and PHP 8.
In PR #40336 I was wrong claiming:

> We don't need COMMIT because the transaction will commit itself when we close the connection.

The result was the we removed all the errors messages from the 3 scenarios. But scenario B will produce some SQL that is actually never committed. IE it will silently fail.

I've been trying to figure out a good solution to how or when to start a transaction. I tried out @fbourigault [suggestion](#40336 (comment)) but that would be the same fix as #40055.

---------------

We need a transaction because the SQL includes a `LOCK TABLE`, however, I cannot see a strict need for it. This PR removes `LOCK TABLE` and all transaction juggling. It all seams to work.

I would be happy to get thorough feedback on this PR so we can end the chapter of constantly adding bugs to this part of the component.

@dunglas, you added `LOCK TABLE` in your initial version of this class in #35485, could you share some knowledge if this is a good or bad idea?

Commits
-------

26061a1 Dont lock tables or start transactions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants