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

Kir*_*lla 5 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
}
Run Code Online (Sandbox Code Playgroud)

如果发生一些错误,$Mysql->commit()我们已经在 redis 中有我们的数据并且无法回滚它。最佳做法是什么?

raf*_*ian 6

MySQL的5.0.3及以上版本支持XA,但Redis的没有,所以你不能进行传统意义上的分布式事务的其中两个参与者理解PREPARECOMMITROLLBACK语义。

在您的情况下,由于您只有 1 个不符合 XA 的参与者 (redis),因此请最后执行 redis 工作。如果redis操作成功,则commit MySQL。如果redis不成功,回滚MySQL。因此,就最佳实践而言,您走在正确的轨道上,因为您别无选择。你没有说你对redis做了多少操作,如果只有一个,你没问题,但是如果你在做多个redis操作MULTI/EXEC并且出现故障,你需要回滚MySQL撤消redis操作那是成功的,因为MULTI/EXEC不是原子的。