Skip to content

Consecutive migrations throw "SAVEPOINT DOCTRINE_... does not exist" when second migration "isTransactional" set to false #1531

@Jalliuz

Description

@Jalliuz

In doctrine/dbal 3.9.4 I have "use_savepoints" option enabled, (Deprecated option, I know, but the option was there since some time)

doctrine:
    dbal:
        use_savepoints: true

I have one migration where I want to bulk commit per 1000 UPDATE queries in a while loop

final class Version20251015152029 extends AbstractMigration
{
    public function isTransactional(): bool
    {
        return false;
    }

    public function up(Schema $schema): void
    {
        $stmt = $this->connection->executeQuery('SELECT id FROM some_table');

        $i = 0;
        $this->connection->beginTransaction();
        while (($row = $stmt->fetchAssociative()) !== false) {
            $this->connection->executeQuery('UPDATE some_table SET something = 'some_value' WHERE id = :id', ['id' => $row['id']]);
            
            // Bulk commit per 1000 UPDATE queries
            if (++$i % 1000 === 0) {
                $this->connection->commit();
                $this->connection->beginTransaction();
            }
        }

        $this->connection->commit();
    }

This worked perfectly when I ran this migration on its own
bin/console doctrine:migrations:execute --up 'DoctrineMigrations\Version20251015152029'

But as soon as I wanted to do multiple consecutive migrations
bin/console doctrine:migrations:migrate
And for some reason I would have another migration before this one, then this second non transactional migration failed.
[error] Migration DoctrineMigrations\Version20251015152029 failed during Execution. Error: "An exception occurred while executing a query: SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT DOCTRINE_2 does not exist"

So this error only happened when this was not the first migration in the process

After a lot of debugging I found out that removing this option solved the issue:

doctrine:
    dbal:
        ...
        # use_savepoints: true

After all I see that this option is deprecated. But I want to post the bug. Because in DBAL 4 this is standard set to true?
This is a dangerous problem because it might only occur when deploying to production. The problem only arises if this migration has another migration before in the migration process. I have not tested this in dbal 4

Don't know if it matters but the migration before this one was one where isTransactional was default, so true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions