Zend Framework 数据库事务 - 无法回滚

6

首先,让我先说一下。我的问题与这个类似:Cannot rollback transaction in Zend Framework

我的表始终都是innoDB,一直都是。我已经检查了相关的表,它确实是innoDB。现在来看看问题所在。

我有一个数据库实例和模型实例通过这个事务同时操作同一个数据库:

$db->beginTransaction();

try { 
  // Run an insert
  $model_record->insert(array('single_item' => 'its value'));

  // More logic, and run an update.
  $model_record->this_value = 'that';

  // Save it
  $model_record->save();

  //Commit the transaction
  $db->commit();
} catch (Exception $e) {

  // It finds the rollback, yet does nothing.
  $db->rollBack();  
}

现在,我发现这个功能无法正常工作的原因是,在测试中超出了一行字符限制,以确保所有的逻辑都是正确的。

它没有回滚。除此之外,记录“single_item”已经存在于数据库中。但是更新后的值并没有。

我是不是漏掉了一些小细节?我从来没有在MySQL和innoDB中遇到过事务问题。这可能与MySQL或ZF有关吗?任何见解都很有帮助,谢谢。

更新:

我进行了几次测试,以下是一些可能有用的结果:

    $this->_db->beginTransaction();

    // This works
    $this->_db->insert('table_a', 
        array(
           'a_field' => 'transaction test',
        )
    );

    // This does not work, at all.  It inserts and does not rollback.  There is no commit.
    $_table_a_model->insert(
        array(
            'a_field' => 'transaction test',
        )
    );

    $this->_db->rollback();

额外更新 您需要获取模型的实例,并在其上调用事务。

$the_model = $this->_model->getAdapter();
$the_model->beginTransaction();

这样做不留下为多个表执行事务的空间,而不是为每个模型实例执行多个事务。有没有其他办法而不必返回到基本数据库实例?

$model_record->foo() 方法中是否有任何一个会导致异常触发? - ficuscr
他们不会。如果没有任何异常抛出,一切都能正常工作。我遇到的异常是直接来自MySQL的。 - wesside
我刚刚使用正确的数据进行了测试,在 commit() 之前抛出了异常,但没有回滚。 - wesside
2个回答

4

我明白了。我需要使用$db = Zend_Db_Table_Abstract::getDefaultAdapter();,然后在此基础上运行我的事务,这样多个模型中的所有操作都可以在单个事务下一起工作。如果有人有解决方法,请随意评论。


太棒了!非常感谢!但是……为什么会这样呢?有解释吗? 在我的Bootstrap.php中,我创建了$db并将其保存到Zend_Registry中,并将其设置为Zend_Db_Table_Abstract ::setDefaultAdapter($db)。那么,为什么在我从注册表中提取并使用它后它不起作用呢?您的解决方案完美地解决了这个问题! - Enriqe

1
也许你的测试用例超过了最大字符限制,只是截断了插入的数据,并没有引发异常?假设如果你输入表名时出现了错误,你会得到一个异常(如果没有,请确保PDO::ERRMODE_EXCEPTION已启用)。如果你真的引发了异常,那么catch块应该会触发回滚,如果提交而不是回滚,而你从未调用rollback(),那么结果似乎就是你应该期望的。
哦,看看你的代码,我们应该确保$model类中的$db实例与控制器中的相同。在这里查看here,看看如何在整个过程中使用相同的$db句柄。 编辑: @Wes找到了解决方法。“我必须使用$db = Zend_Db_Table_Abstract::getDefaultAdapter();然后在其中运行我的事务,以便多个模型中的所有操作都在单个事务下一起工作。如果有人有解决方法,请随意评论。”

我向您保证,它通过mysql抛出了一个异常,而且实际上已经被捕获。似乎没有任何区别。如果所有交易项目都消失了,同样的功能也是如此。 - wesside
更新了问题,并附加了更多的结果。 - wesside
我的模型都是从Zend_Db_Table_Abstract继承的。 - wesside
我不知道。可能没有得到相同的 $db 实例(Db_Adapter),或者你一直在打错字,这个表实际上是 MyISAM :) 我的意思是,我所阅读的所有内容(http://zend-framework-community.634137.n4.nabble.com/DB-transactions-and-Zend-Db-Table-td670868.html)以及查看我的代码都表明这应该可以正常工作。 - ficuscr
肯定不是这样的,我确定只是有些小问题我没有想到。但我真的不喜欢在一个方法中同时运行3个事务。 - wesside
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接