Doctrine 2 迁移 - postUp 中的事务

问题描述 投票:0回答:1

postUp()
方法中完成结构数据库更改后,我想使用
up()
导入一些数据。导入应使用 DBAL API 在事务中完成。然而,插入似乎是一个接一个地提交的。如果在导入过程中发生错误(例如“重复密钥”错误),则可以观察到这一点。即使启动了回滚,在错误之前执行的插入也将被提交到数据库。似乎破坏事务行为的是
up()
方法中的任何 DDL 语句。

考虑以下因素:

public function up(Schema $schema) : void
{
    // this up() migration is auto-generated, please modify it to your needs
    $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

    $this->addSql('CREATE TABLE user (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE UTF8_unicode_ci ENGINE = InnoDB');

}

public function postUp(Schema $schema)
{

        /**
         * @var EntityManager $em
         */
        $em = $this->container->get('doctrine.orm.entity_manager');

        $em->getConnection()->transactional(function ($conn) {

             $conn->executeUpdate("INSERT INTO user (id,name) VALUES(1,'Josh')");
             $conn->executeUpdate("INSERT INTO user (id,name) VALUES(1,'Will')");
        });
}

现在,第二个插入语句将导致“1062:重复键”错误,并将触发对连接实例上的

rollback()
的调用。但是,实际回滚不会发生,并且第一个插入的行保留在数据库中。我实际上使用调试器跟踪了执行情况,并且
commit()
从未被调用,
rollback()
被调用,因为它应该,但最终结果似乎相反。我还尝试执行插入而不将它们包装在
transactional()
中,行为是相同的。

但是,如果

up()
方法中没有 DDL 语句(例如,如果用户表已存在),则事务按预期工作,并且
user
表保持为空,无论是否在事务中包装插入语句。我在这里做错了什么或理解错误以及如何正确执行此操作?

php doctrine symfony-3.4
1个回答
0
投票
  1. 您在 id 字段上有一个主键。所以它是独一无二的。 - 主要问题
  2. 你编写executeUpdate。也许你想要插入?
© www.soinside.com 2019 - 2024. All rights reserved.