写入两个或多个不同数据存储时的事务

时间:2013-05-08 13:11:03

标签: mysql transactions redis

假设我们有两个数据存储:MySQL(innodb)& Redis的。 我们需要将一些数据写入两个存储器并在事务中执行。

try {
  $Mysql->transaction();   //start mysql transaction
  $Mysql->somecommands();  //exec some sql
  $Redis->multi();         //start redis transaction
  $Redis->somecommands();  //exec some redis commands
  $Redis->exec()           //redis commit
  $Mysql->commit();        //mysql commit
} catch (Exception $e) {
  $Mysql->rollback();      //mysql rollback
  $Redis->discard();       //redis rollback
}

如果在$Mysql->commit()上发生了一些错误,我们已经将数据放在redis中,无法回滚它。什么是最佳实践?

1 个答案:

答案 0 :(得分:3)

MySQL 5.0.3及更高版本支持XA,但Redis不支持,因此您无法执行传统意义上的分布式事务,其中参与者都理解PREPARECOMMITROLLBACK语义。

在您的情况下,由于您只有1个非XA兼容参与者(redis),因此只需重新开始工作。如果redis操作成功,则提交MySQL。如果redis不成功,则回滚MySQL。因此,就最佳实践而言,由于您别无选择,因此您处于正确的轨道上。你没有说你正在对redis进行多少操作,如果它只有一个,你很好,但是如果你用MULTI/EXEC进行多次redis操作并且某些操作失败,你将需要回滚MySQL 撤消自MULTI/EXEC不是原子的以来成功的redis操作。