Laravel中常见的错误与解决方法小结


Posted in Javascript onAugust 30, 2016

一、报错: 「Can't swap PDO instance while within transaction」

通过查询 Laravel 源代码,可以确认异常是在 setPdo 方法中抛出的: 

<?php

public function setPdo($pdo)
{
  if ($this->transactions >= 1) {
    throw new RuntimeException("
      Can't swap PDO instance while within transaction.
    ");
  }

  $this->pdo = $pdo;

  return $this;
}

?>

按字面意思理解,出现此错误是因为在开启了事务的情况下,切换了数据库连接。不过有时候,即便代码里没有显式的切换数据库连接,也有可能出现此错误。比如说在执行查询语句出错的时候,系统会通过 tryAgainIfCausedByLostConnection 方法判断问题是不是因为丢失连接导致的,如果是,那么系统会通过 reconnect 方法重新连接,在重新连接的时候,系统会通过 disconnect 方法执行一些清理工作,其中调用了 setPdo 方法。

理清了前因后果,自然就知道如何解决问题了:检查网络情况,确认数据库连接丢失的原因,这可能是某个设备有问题,也可能是某个 timeout 设置不当所致。一个相对 dirty 的处理方法是在查询前执行一下 DB::reconnect() 方法重新连接一下数据库。

二、报错:「Cannot delete job: NOT_FOUND」

此问题实际上和 Laravel 没太大关系,而是队列服务 Beanstalk 导致的。

Laravel中常见的错误与解决方法小结
Beanstalk

要解决这个问题,需要先理解一个消息的生命周期:当一个消息被放入队列的时候,它就进入了 READY 状态,与此同时,它会关联一个 TTR(time to run) 计时器,表示此消息允许运行的时间,当此消息被消费时,它就进入了 RESERVED 状态,消费完后,此消息就会被删除,如果消费的时间过长,比 TTR 还长,那么系统会认为认为此消费者已经挂了,进而会把消息从 RESERVED 状态退回到 READY 状态,交给另一个消费者重新处理。于是乎同一个消息可能会被多个消费者处理,第一个处理完的消费者可以正常的删除消息,而其余的消费者在删除消息的时候就会报无法删除的错误。

解决方法很简单,首先,需要确保 TTR 的设置不能太小;其次,实际上 Beanstalk 提供了一个专门的 touch 命令来解决执行时间过长的问题,此外,有些时候我们可能需要在应用层面上通过加锁来规避同一个消息被多个消费者同时处理的情况。

三、报错:「No query results for model」

在激活了 Laravel 读写分离的前提下,当消费者处理消息的时候,可能会收到类似错误。一个有潜在问题的队列命令大概如下所示: 

<?php

class Foo extends Command implements SelfHandling, ShouldBeQueued
{
  use InteractsWithQueue, SerializesModels;

  protected $bar;

  public function __construct($id)
  {
    $this->bar = Bar::find($id);
  }

  public function handle()
  {
    // $this->bar
  }
}

?>

很明显,当开启了 Laravel 读写分离的时候,因为主从延迟的缘故,所以 find 可能查询不到相应的数据,一旦我们分析到了这里,那么很可能会把写法修改成下面的样子:

<?php

class Foo extends Command implements SelfHandling, ShouldBeQueued
{
  use InteractsWithQueue, SerializesModels;

  protected $bar;

  public function __construct($id)
  {
    $this->bar = Bar::onWriteConnection()->find($id);
  }

  public function handle()
  {
    // $this->bar
  }
}

?>

也就是说,通过 Laravel 的 onWriteConnection 方法把查询固定在主服务器上,不过实际上无效。问题症结在于反序列化的时候,系统会在从服务器上一次 findOrFail 调用。 

<?php

protected function getRestoredPropertyValue($value)
{
  return $value instanceof ModelIdentifier
    ? (new $value->class)->findOrFail($value->id) : $value;
}

?>

因为我们无法 HACK 到框架内部,所以 onWriteConnection 就没有意义了。其实换个角度看问题,只要在系列化的时候,保证别用数据库对象做属性即可:

<?php

class Foo extends Command implements SelfHandling, ShouldBeQueued
{
  use InteractsWithQueue, SerializesModels;

  protected $id;

  public function __construct($id)
  {
    $this->id = $id;
  }

  public function handle()
  {
    $bar = Bar::onWriteConnection()->find($this->id);
  }
}

?>

四、总结

以上就是我在使用Laravel遇到的几个有代表性的报错以及解决方案,如果有问题欢迎大家一起交流。希望这篇文章对大家的学习或者工作能带来一定的帮助。

Javascript 相关文章推荐
jquery 实现checkbox全选,反选,全不选等功能代码(奇数)
Oct 24 Javascript
一个js导致的jquery失效问题的解决方法
Nov 27 Javascript
js获取url参数代码实例分享(JS操作URL)
Dec 13 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
Dec 08 Javascript
Js可拖拽放大的层拖动特效实现方法
Feb 25 Javascript
jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
Apr 30 Javascript
js实现TAB切换对应不同颜色的代码
Aug 31 Javascript
jQuery插件实现文件上传功能(支持拖拽)
Aug 27 Javascript
Bootstrap精简教程中秋大放送
Sep 15 Javascript
vue 项目中使用Loading组件的示例代码
Aug 31 Javascript
vue实现列表拖拽排序的功能
Nov 02 Javascript
JS实现超级好看的鼠标小尾巴特效
Dec 01 Javascript
js中常用的Tab切换效果(推荐)
Aug 30 #Javascript
基于cssSlidy.js插件实现响应式手机图片轮播效果
Aug 30 #Javascript
JavaScript探测CSS动画是否已经完成的方法
Aug 30 #Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
Aug 30 #Javascript
很棒的js Tab选项卡切换效果
Aug 30 #Javascript
js改变透明度实现轮播图的算法
Aug 24 #Javascript
标准的js无缝滚动效果
Aug 30 #Javascript
You might like
PHP中实现Bloom Filter算法
2015/03/30 PHP
php实现的递归提成方案实例
2015/11/14 PHP
让js弹出窗口居前显示的实现方法
2013/07/10 Javascript
javascript ready和load事件的区别示例介绍
2013/08/30 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
2014/04/15 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
js监听鼠标事件控制textarea输入字符串的个数
2014/09/29 Javascript
浅谈javascript的Array.prototype.slice.call
2015/08/31 Javascript
jQuery采用连缀写法实现的折叠菜单效果
2015/09/18 Javascript
用户代理字符串userAgent可实现的四个识别
2015/09/20 Javascript
IE8利用自带的setCapture和releaseCapture解决iframe的拖拽事件方法
2016/10/25 Javascript
JavaScript cookie详解及简单实例应用
2016/12/31 Javascript
vue数据双向绑定原理解析(get &amp; set)
2017/03/08 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
vue全局自定义指令-元素拖拽的实现代码
2019/04/14 Javascript
解决layui富文本编辑器图片上传无法回显的问题
2019/09/18 Javascript
vue.js+ElementUI实现进度条提示密码强度效果
2020/01/18 Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
2020/09/01 Javascript
[54:10]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
python在windows命令行下输出彩色文字的方法
2015/03/19 Python
利用Python批量生成任意尺寸的图片
2016/08/29 Python
Pycharm保存不能自动同步到远程服务器的解决方法
2019/06/27 Python
Python Lambda函数使用总结详解
2019/12/11 Python
CSS3基础(RGBa、text-shadow、box-shadow、border-radius)
2012/11/13 HTML / CSS
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
请写出 BOOL flag 与"零值"比较的 if 语句
2016/02/29 面试题
大一自我鉴定范文
2013/10/04 职场文书
生产车间主管岗位职责
2013/12/28 职场文书
2014年乡镇人大工作总结
2014/11/25 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
黄埔军校观后感
2015/06/10 职场文书
教育读书笔记
2015/07/02 职场文书
python中requests库+xpath+lxml简单使用
2021/04/29 Python
golang 实现并发求和
2021/05/08 Golang
纯html+css实现打字效果
2021/08/02 HTML / CSS