我的代码中有很多事务,如果在执行这些不会触发提交或回滚的事务之一时发生错误,那么数据库将被锁定,并且任何后续访问数据库的尝试都会导致此:
production.ERROR: PDOException: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded;尝试在/home/forge/default/vendor/laravel/framework/src/Illuminate/Database/Connection.php:390 中重新启动事务
在 Controller 中:
DB::beginTransaction();
try {
//Code that uses exec() to process some images. <-- If code breaks here, then the above error appears on subsequent requests.
//Code that accesses the database
}
catch(\Exception $e){
DB::rollback();
throw $e;
}
DB::commit();
因此,即使是 php artisan migrate:refresh 或 php artisan migrate:reset 也会停止工作。我应该如何解决这个问题?
最佳答案
以下是我的经验中的一些提示...
如果您在进行测试驱动开发,请找出哪个测试组合会产生错误。利用您的生态系统提供的任何机制来选择性地运行测试(例如:@group only
on test methods and phpunit --group only
)
接下来,减少锁等待超时(SET GLOBAL innodb_lock_wait_timeout = 10
)。通过这种方式,您可以获得快速反馈,而不必整天等待测试运行。里程可能会有所不同。根据您的具体情况进行调整。
第三,寻找未关闭的事务,即在没有回滚或提交的情况下开始。事实证明这正是我的问题所在。我的 try/catch 没有包装足够的逻辑,并且在开始事务和 try-catch-rollback 之间出错。
第四,考虑将事务的所有部分放在同一个 try-catch 中,这样可以确保所有部分都在那里并且易于看到。示例:
try {
DB::beginTransaction();
$this->someMethodThatMightThrow();
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
这是我的两分钱。希望对互联网上的人有用。
关于php - Laravel - 超过锁定等待超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38866560/