dongzhan2461
dongzhan2461
2012-09-10 18:32
浏览 105
已采纳

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

Alright, let me get this out of the way first. My question is similar to this: Cannot rollback transaction in Zend Framework

My tables are always innoDB, always. I've checked the table in question and it is indeed 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. But the updated values, were not.

Am I completely missing something small, I've never had transaction issues with MySQL & innoDB. Could this be MySQL related or ZF related? 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?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dongxieyi9115
    dongxieyi9115 2012-09-10 21:42
    已采纳

    I figured it out. 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.

    点赞 评论
  • dsdxlibt98300
    dsdxlibt98300 2012-09-10 18:45

    Maybe your test case, exceeding the max chars just truncates the data inserted and does not in fact raise an exception? 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). 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.

    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. Look here and see how same $db handle is used throughout.

    Edit: @Wes figured it out. "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."

    点赞 评论

相关推荐