Laravel中常见的错误与解决方法小结
一、报错: 「Can't swap PDO instance while within transaction」
通过查询 Laravel 源代码,可以确认异常是在 setPdo
方法中抛出的:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
tryAgainIfCausedByLostConnection
方法判断问题是不是因为丢失连接导致的,如果是,那么系统会通过 reconnect
方法重新连接,在重新连接的时候,系统会通过 disconnect
方法执行一些清理工作,其中调用了 setPdo
方法。百牛信息技术bainiu.ltd整理发布于博客园
理清了前因后果,自然就知道如何解决问题了:检查网络情况,确认数据库连接丢失的原因,这可能是某个设备有问题,也可能是某个
timeout
设置不当所致。一个相对 dirty
的处理方法是在查询前执行一下 DB::reconnect()
方法重新连接一下数据库。二、报错:「Cannot delete job: NOT_FOUND」
此问题实际上和 Laravel 没太大关系,而是队列服务 Beanstalk 导致的。
文章图片
Beanstalk
要解决这个问题,需要先理解一个消息的生命周期:当一个消息被放入队列的时候,它就进入了
READY
状态,与此同时,它会关联一个 TTR(time to run)
计时器,表示此消息允许运行的时间,当此消息被消费时,它就进入了 RESERVED
状态,消费完后,此消息就会被删除,如果消费的时间过长,比 TTR
还长,那么系统会认为认为此消费者已经挂了,进而会把消息从 RESERVED
状态退回到 READY
状态,交给另一个消费者重新处理。于是乎同一个消息可能会被多个消费者处理,第一个处理完的消费者可以正常的删除消息,而其余的消费者在删除消息的时候就会报无法删除的错误。解决方法很简单,首先,需要确保
TTR
的设置不能太小;其次,实际上 Beanstalk
提供了一个专门的 touch
命令来解决执行时间过长的问题,此外,有些时候我们可能需要在应用层面上通过加锁来规避同一个消息被多个消费者同时处理的情况。三、报错:「No query results for model」
在激活了 Laravel 读写分离的前提下,当消费者处理消息的时候,可能会收到类似错误。一个有潜在问题的队列命令大概如下所示:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
find
可能查询不到相应的数据,一旦我们分析到了这里,那么很可能会把写法修改成下面的样子:?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
onWriteConnection
方法把查询固定在主服务器上,不过实际上无效。问题症结在于反序列化的时候,系统会在从服务器上一次 findOrFail
调用。?
1 2 3 4 5 6 7 8 9 | |
HACK
到框架内部,所以 onWriteConnection
就没有意义了。其实换个角度看问题,只要在系列化的时候,保证别用数据库对象做属性即可:?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
以上就是我在使用Laravel遇到的几个有代表性的报错以及解决方案,如果有问题欢迎大家一起交流。希望这篇文章对大家的学习或者工作能带来一定的帮助。
转载于:https://www.cnblogs.com/bainiu/p/7560523.html
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- “成长”读书社群招募
- 2020-04-07vue中Axios的封装和API接口的管理