php - 在事务中更新不同的数据库(Laravel)

标签 php mysql database laravel transactions

对于我们用 Laravel 编写的 Web 应用程序,我们使用事务来更新数据库。我们已经将数据跨不同的数据库分开(为方便起见,我们说“应用程序”和“用户”)。在应用程序更新期间,会触发一个事件来更新用户数据库中的一些用户统计信息。但是,此应用程序更新可能作为应用程序数据库事务的一部分被调用,因此代码结构如下所示。

DB::connection('app')->beginTransaction();
// ...
DB::connection('user')->doStuff();
// ...
DB::connection('app')->commit();

似乎在游戏事务中尝试在用户连接上启动事务(因为单个查询已经创建隐式事务)不起作用,导致死锁(参见 InnoDB status output )。我还使用了 innotop 来获取更多信息,但是虽然它显示了锁定等待,但没有显示它被哪个查询阻止了。用户表上有一个锁,但我找不到它的来源。相关输出如下所示:

Lock Wait output Lock output

简单的解决方案是从事务中提取用户操作,但由于实际代码稍微复杂一些(doStuff 实际上发生在事务期间调用的嵌套方法中的某处,并且是从不同的地方调用),这远非微不足道。我非常希望 doStuff 成为事务的一部分,但我看不出事务如何跨越多个数据库。

这种情况导致死锁的原因是什么,是否可以在此事务中对用户数据库运行 doStuff,或者我们是否必须找到一个完全不同的解决方案,例如对事件进行排队之后执行?

最佳答案

我找到了一种使用变通方法解决此问题的方法。我的假设是它试图使用应用程序连接来更新用户数据库,但在强制它使用用户连接后,它仍然锁定。然后我将其切换并使用应用程序连接来更新用户数据库。由于我们在数据库之间进行了连接,因此我们拥有具有适当访问权限的数据库用户,所以这不是问题。这实际上解决了问题。

也就是说,最后的代码竟然是这样的

DB::connection('app')->beginTransaction();
// ...
DB::connection('app')->table('user.users')->doStuff(); // Pay attention to this line!
// ...
DB::connection('app')->commit();

关于php - 在事务中更新不同的数据库(Laravel),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33371830/

相关文章:

mysql - 确定字段中的最大字符数

mysql - 如何进行亚马逊备份

mysql - 如何将索引添加到日期时间列?

php - 将相对链接变成绝对链接

php - 嵌入式 Web 服务器来运行 php

mysql - 如何在 Sql-server 中对按日期分组的时间求和

javascript - 通过 3 个数组进行过滤以对数据进行排序

android - 如何在 Android 中正确打开/关闭 SQLite 数据库

php - SimpleXML 有 xmlns :xmlns ="" - no way to remove 的声明

php - PHP 中的长文本数据类型