【问题标题】:Doctrine multiple flush commit once教义多次刷新提交一次
【发布时间】:2017-10-18 06:46:12
【问题描述】:

我做了很多搜索但没有成功。 我想了解一下这种情况下的flush()过程。

//Edit updateOptions
public function updateOptions($values){
    setOption('country',$values['country']);
    setOption('city',$values['city']);
    setOption('adress',$values['adress']);
    setOption('CP',$values['CP']);
    setOption('country_code',$values['country_code']);
}


function setOption($name, $value){

     $em = $this->getEntityManager('option.manager');

     $option = $this->getOption($name); //Entity Options
     $option->setValue($value);

     $em->persist($option);
     $em->flush();
}

当我查看 mysql.log 或分析器时,我发现了这个:

START TRANSACTION
UPDATE options SET value = 'France' WHERE name = 'country';
COMMIT
START TRANSACTION
SAVEPOINT DOCTRINE2_SAVEPOINT_2
UPDATE options SET value = 'Paris' WHERE name = 'city';
RELEASE SAVEPOINT DOCTRINE2_SAVEPOINT_2
SAVEPOINT DOCTRINE2_SAVEPOINT_2
UPDATE options SET value = 'Rue de Rivoli' WHERE name = 'adress';
RELEASE SAVEPOINT DOCTRINE2_SAVEPOINT_2
SAVEPOINT DOCTRINE2_SAVEPOINT_2
UPDATE options SET value = '75001' WHERE name = 'CP';
RELEASE SAVEPOINT DOCTRINE2_SAVEPOINT_2
SAVEPOINT DOCTRINE2_SAVEPOINT_2
UPDATE options SET value = '33' WHERE name = 'country_code';
RELEASE SAVEPOINT DOCTRINE2_SAVEPOINT_2
ROLLBACK

只有第一个被更新/提交,我明白了,但我不明白为什么下一个被回滚?

如果我在循环中使用 setOption() 也会发生这种情况。

帮助会很棒。 提前致谢。

【问题讨论】:

  • 您能详细说明一下吗?目前,您每次调用 setOption 时都会刷新到数据库。
  • 方法名为 updateOptions 单词 update - 表示条目已经在 db 中,您的日志显示我们只执行了 UPDATE 语句而不是 INSERT,因此您应该删除 $em->persist() 部分。
  • @Dymens1:确切地说,我想知道我为什么会遇到这种情况。 setOption() 在其他一些页面中使用,对于这个例子,我写了“UPDATE”,但它对“INSERT”做同样的事情,这只是一个例子。我想了解这种情况下的事务,如果可能的话,为flush()找到一个解决方案。

标签: mysql symfony doctrine-orm transactions flush


【解决方案1】:

不要每次都调用persist() 和flush()。我想这可能是原因。由于您没有明确告诉 EM 开始交易,它可能会尝试通过 persist()flush() 的组合来猜测它

尝试以下:

扩展您的 updateOptions 方法

public function updateOptions ()
{
    $em = $this->getEntityManager( 'option.manager' );

    $em->beginTransaction();

    setOption( 'country', 'France' );
    setOption( 'city', 'Paris' );
    setOption( 'adress', 'Rue de Rivoli' );
    setOption( 'CP', '75001 ' );
    setOption( 'country_code', '33' );

    $em->flush(); //just notif EM there're records to UPDATE

    //$success = false; 

    try
    {
        $em->commit();
        //$success = true;
    }
    catch ( \Exception $ex )
    {
        $em->rollback();
        // my fav is followinn: in DEV re-throw exception so you can inspect all in symfony-debug-bar
        // in prod just additional emergency log (monolog + swiftmailer) so you get an email

        if( $this->get( 'kernel' )->getEnvironment() !== 'prod' )
        {
            throw $ex;
        }
        $this->get( 'logger' )->addEmergency( 'Oh nooo! Not again :/' );

    }

 //return $success;
}

function setOption($name, $value){

     $option = $this->getOption($name); //Entity Options
     $option->setValue($value);
}

【讨论】:

    猜你喜欢
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2016-11-05
    • 1970-01-01
    • 2016-04-15
    • 2013-01-10
    相关资源
    最近更新 更多