简体   繁体   English

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

[英]Zend Framework Database Transaction - Can't rollback

Alright, let me get this out of the way first. 好吧,让我先把它弄清楚。 My question is similar to this: Cannot rollback transaction in Zend Framework 我的问题与此类似: 无法在Zend Framework中回滚事务

My tables are always innoDB, always. 我的表永远都是innoDB。 I've checked the table in question and it is indeed innoDB. 我检查了有问题的表,它确实是innoDB。 On to the problem.. 关于问题..

I have a database instance, and model instances running through this transaction hitting the same database: 我有一个数据库实例,并且通过此事务运行的模型实例命中同一个数据库:

$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();  
}

Now, the reason I found this to not be working is I exceeded the character limit on a row during a test to make sure all the logic in place was correct. 现在,我发现这不起作用的原因是我在测试期间超出了行上的字符限制,以确保所有逻辑都正确。

It did not rollback. 它没有回滚。 On top of that the record with 'single_item', was in the database. 最重要的是,带有'single_item'的记录在数据库中。 But the updated values, were not. 但更新的价值观并非如此。

Am I completely missing something small, I've never had transaction issues with MySQL & innoDB. 我完全错过了一些小的东西,我从来没有遇到MySQL和innoDB的交易问题。 Could this be MySQL related or ZF related? 这可能是MySQL相关的还是ZF相关的? Any insight is helpful, thanks. 任何见解都很有帮助,谢谢。

Update: 更新:

I've been conducting a few more tests and here are a few results that might help: 我一直在进行一些测试,这里有一些结果可能会有所帮助:

    $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();

Additional Update You need to get the instance of the model, and call a transaction on that. 其他更新您需要获取模型的实例,并在其上调用事务。

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

This leaves no room for transactions for multiple tables, without doing multiple transactions for each model instance. 这为多个表的事务留下了空间,而不为每个模型实例执行多个事务。 Any ideas out there without reverting to the base database instance? 没有恢复到基础数据库实例的任何想法?

I figured it out. 我想到了。 I have to use $db = Zend_Db_Table_Abstract::getDefaultAdapter(); 我必须使用$db = Zend_Db_Table_Abstract::getDefaultAdapter(); and then run my transactions off that so all operations in multiple models work together under a single transaction. 然后运行我的事务,以便多个模型中的所有操作在单个事务下一起工作。 If anyone has a fix for that, feel free to comment. 如果有人有解决方法,请随时发表评论。

Maybe your test case, exceeding the max chars just truncates the data inserted and does not in fact raise an exception? 也许你的测试用例,超过max chars只是截断插入的数据,实际上并没有引发异常? Assuming that if you do something like mistype the name of a table you will get an exception (if not definitely check PDO::ERRMODE_EXCEPTION is enabled). 假设如果你做错误输入表的名称,你将得到一个异常(如果不是绝对检查PDO :: ERRMODE_EXCEPTION已启用)。 If you are truly raising an exception that catch block should fire and rollback, if the commit is instead firing and you never call rollback() it sounds like the result is what you should expect. 如果你真的提出了一个异常,catch块应该触发和回滚,如果提交反而触发,你永远不会调用rollback(),听起来结果是你应该期待的。

Oh, and looking at your code suppose we should make sure that $db is the same instance in your model class as on that controller. 哦,看看你的代码假设我们应该确保$ db是你的模型类中与该控制器上相同的实例。 Look here and see how same $db handle is used throughout. 看看这里 ,看看整个过程中是如何使用$ db句柄的。

Edit: @Wes figured it out. 编辑: @Wes想出来了。 "I have to use $db = Zend_Db_Table_Abstract::getDefaultAdapter(); and then run my transactions off that so all operations in multiple models work together under a single transaction. If anyone has a fix for that, feel free to comment." “我必须使用$ db = Zend_Db_Table_Abstract :: getDefaultAdapter();然后运行我的事务,以便多个模型中的所有操作在单个事务下一起工作。如果有人有解决方法,请随时发表评论。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM