Yii2.0 操作事务多个数据库

发布于 2022-09-11 15:04:44 字数 247 浏览 17 评论 0

我现在是这样的,项目有很多的数据库,都是在同一个mysql服务器下的,在main.php里面有db,db2,db3 现在是这样的有个入库操作,A表来自于db2,B表来自于db3,在使用事务的时候是这句:

$transaction = \Yii::$app->get('db2')->beginTransaction(); 

我不清楚到底写get('db2')还是get('db3')还是随便都可以??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖不如嘢 2022-09-18 15:04:44

mysql应该不支持分布式事物。

草莓味的萝莉 2022-09-18 15:04:44

mysql单纯的事务是不支持跨库的。真要做的话可以使用XA Transactions

1.确认是否开启XA事务支持

clipboard.png
如上,innodb_support_xa为ON 表示已开启,否则需先开启

SET innodb_support_xa = ON

2.XA事务实现

$xid = uniqid("xa_"); // 必须唯一

//两个库指定同一个事务id,表明这两个库的操作处于同一事务中
\Yii::$app->db2->createCommand("XA START '$xid'")->execute();
\Yii::$app->db3->createCommand("XA START '$xid'")->execute();

try {

    // 如下为具体业务代码
    $affectCount = \Yii::$app->db2->createCommand("UPDATE test SET aa='aa' WHERE id=1")->execute();
    if($affectCount == false) {
        throw new \Exception("db2执行失败");
    }

    $affectCount = \Yii::$app->db3->createCommand("UPDATE test2 SET bb='bb' WHERE id=1")->execute();
    if($affectCount == false) {
        throw new \Exception("db3执行失败");
    }

    //阶段1:db2提交准备就绪
    \Yii::$app->db2->createCommand("XA END '$xid'")->execute();
    \Yii::$app->db2->createCommand("XA PREPARE '$xid'")->execute();
    //阶段1:$db3提交准备就绪
    \Yii::$app->db3->createCommand("XA END '$xid'")->execute();
    \Yii::$app->db3->createCommand("XA PREPARE '$xid'")->execute();

    //阶段2:提交两个库
    \Yii::$app->db3->createCommand("XA COMMIT '$xid'")->execute();
    \Yii::$app->db3->createCommand("XA COMMIT '$xid'")->execute();

} catch(\Exception $e) {

    \Yii::$app->db2->createCommand("XA ROLLBACK '$xid'")->execute();
    \Yii::$app->db3->createCommand("XA ROLLBACK '$xid'")->execute();
    die($e->getMessage());
}

代码实现参考如下文章,供参考,未测试
https://blog.csdn.net/soonfly...

实际上使用事务会大大的影响性能,如非业务足够特别,一定要使用分布式事务强烈不建议使用,甚至单库的事务也谨慎使用。

XA transaction support is limited to the InnoDB storage engine.
XA事务只在InnoDB存储引擎中支持

Prior to MySQL 5.7.7, XA transactions were not compatible with replication at all. This was because an XA transaction that was in PREPARED state would be rolled back on clean server shutdown or client disconnect. Similarly, an XA transaction that was in PREPARED state would still exist in PREPARED state in case the server was shutdown abnormally and then started again, but the contents of the transaction could not be written to the binary log. In both of these situations the XA transaction could not be replicated correctly.
官方文档说明,在mysql 5.5.7版本之前,XA也不能完全保证一致性。

通过异步的手段保证事务的最终一致是比较合理的思路。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文