欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Laravel中常見的錯誤與解決方法小結(jié)

 更新時間:2016年08月30日 09:36:37   投稿:daisy  
大家在用Laravel框架期間可能會遇到了不少問題,現(xiàn)在我將自己遇到的一些問題總結(jié)出來,有一些調(diào)試起來著實(shí)不太容易,本文篩選出幾個,希望這篇文章能讓大家在PHP開發(fā)中少走一些彎路。

一、報(bào)錯: 「Can't swap PDO instance while within transaction」

通過查詢 Laravel 源代碼,可以確認(rèn)異常是在 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;
}

?>

按字面意思理解,出現(xiàn)此錯誤是因?yàn)樵陂_啟了事務(wù)的情況下,切換了數(shù)據(jù)庫連接。不過有時候,即便代碼里沒有顯式的切換數(shù)據(jù)庫連接,也有可能出現(xiàn)此錯誤。比如說在執(zhí)行查詢語句出錯的時候,系統(tǒng)會通過 tryAgainIfCausedByLostConnection 方法判斷問題是不是因?yàn)閬G失連接導(dǎo)致的,如果是,那么系統(tǒng)會通過 reconnect 方法重新連接,在重新連接的時候,系統(tǒng)會通過 disconnect 方法執(zhí)行一些清理工作,其中調(diào)用了 setPdo 方法。

理清了前因后果,自然就知道如何解決問題了:檢查網(wǎng)絡(luò)情況,確認(rèn)數(shù)據(jù)庫連接丟失的原因,這可能是某個設(shè)備有問題,也可能是某個 timeout 設(shè)置不當(dāng)所致。一個相對 dirty 的處理方法是在查詢前執(zhí)行一下 DB::reconnect() 方法重新連接一下數(shù)據(jù)庫。

二、報(bào)錯:「Cannot delete job: NOT_FOUND」

此問題實(shí)際上和 Laravel 沒太大關(guān)系,而是隊(duì)列服務(wù) Beanstalk 導(dǎo)致的。


Beanstalk

要解決這個問題,需要先理解一個消息的生命周期:當(dāng)一個消息被放入隊(duì)列的時候,它就進(jìn)入了 READY 狀態(tài),與此同時,它會關(guān)聯(lián)一個 TTR(time to run) 計(jì)時器,表示此消息允許運(yùn)行的時間,當(dāng)此消息被消費(fèi)時,它就進(jìn)入了 RESERVED 狀態(tài),消費(fèi)完后,此消息就會被刪除,如果消費(fèi)的時間過長,比 TTR 還長,那么系統(tǒng)會認(rèn)為認(rèn)為此消費(fèi)者已經(jīng)掛了,進(jìn)而會把消息從 RESERVED 狀態(tài)退回到 READY 狀態(tài),交給另一個消費(fèi)者重新處理。于是乎同一個消息可能會被多個消費(fèi)者處理,第一個處理完的消費(fèi)者可以正常的刪除消息,而其余的消費(fèi)者在刪除消息的時候就會報(bào)無法刪除的錯誤。

解決方法很簡單,首先,需要確保 TTR 的設(shè)置不能太??;其次,實(shí)際上 Beanstalk 提供了一個專門的 touch 命令來解決執(zhí)行時間過長的問題,此外,有些時候我們可能需要在應(yīng)用層面上通過加鎖來規(guī)避同一個消息被多個消費(fèi)者同時處理的情況。

三、報(bào)錯:「No query results for model」

在激活了 Laravel 讀寫分離的前提下,當(dāng)消費(fèi)者處理消息的時候,可能會收到類似錯誤。一個有潛在問題的隊(duì)列命令大概如下所示: 

<?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
  }
}

?>

很明顯,當(dāng)開啟了 Laravel 讀寫分離的時候,因?yàn)橹鲝难舆t的緣故,所以 find 可能查詢不到相應(yīng)的數(shù)據(jù),一旦我們分析到了這里,那么很可能會把寫法修改成下面的樣子:

<?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 方法把查詢固定在主服務(wù)器上,不過實(shí)際上無效。問題癥結(jié)在于反序列化的時候,系統(tǒng)會在從服務(wù)器上一次 findOrFail 調(diào)用?!?br />

<?php

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

?>

因?yàn)槲覀儫o法 HACK 到框架內(nèi)部,所以 onWriteConnection 就沒有意義了。其實(shí)換個角度看問題,只要在系列化的時候,保證別用數(shù)據(jù)庫對象做屬性即可:

<?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);
  }
}

?>

四、總結(jié)

以上就是我在使用Laravel遇到的幾個有代表性的報(bào)錯以及解決方案,如果有問題歡迎大家一起交流。希望這篇文章對大家的學(xué)習(xí)或者工作能帶來一定的幫助。

相關(guān)文章

  • JS自定義混合Mixin函數(shù)示例

    JS自定義混合Mixin函數(shù)示例

    這篇文章主要介紹了JS自定義混合Mixin函數(shù),涉及javascript面向?qū)ο蟪绦蛟O(shè)計(jì)中函數(shù)與屬性操作相關(guān)技巧,需要的朋友可以參考下
    2016-11-11
  • 如何用js截取某個字符的前、后面所有字符串

    如何用js截取某個字符的前、后面所有字符串

    這篇文章主要給大家介紹了如何用js截取某個字符的前、后面所有字符串的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 微信小程序自定義可滑動頂部TabBar選項(xiàng)卡實(shí)現(xiàn)頁面切換功能示例

    微信小程序自定義可滑動頂部TabBar選項(xiàng)卡實(shí)現(xiàn)頁面切換功能示例

    這篇文章主要介紹了微信小程序自定義可滑動頂部TabBar選項(xiàng)卡實(shí)現(xiàn)頁面切換功能,結(jié)合實(shí)例形式分析了微信小程序自定義頂部TabBar選項(xiàng)卡頁面切換功能的相關(guān)布局、樣式及功能實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-05-05
  • javascript格式化json顯示實(shí)例分析

    javascript格式化json顯示實(shí)例分析

    這篇文章主要介紹了javascript格式化json顯示,實(shí)例分析了javascript操作json格式化的相關(guān)技巧,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-04-04
  • js拖動滑塊和點(diǎn)擊水波紋效果實(shí)例代碼

    js拖動滑塊和點(diǎn)擊水波紋效果實(shí)例代碼

    在本文里面我們給大家分享了js實(shí)現(xiàn)拖動滑塊和點(diǎn)擊水波紋效果的相關(guān)實(shí)例代碼,有需要的朋友們學(xué)習(xí)下。
    2018-10-10
  • 使用JavaScript獲取URL中的參數(shù)(兩種方法)

    使用JavaScript獲取URL中的參數(shù)(兩種方法)

    這篇文章主要介紹了使用JavaScript獲取URL中的參數(shù)(兩種方法)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • javascript異步編程

    javascript異步編程

    如果編程加入了時間的概念就一切變得非常復(fù)雜。通常我們的程序是飛快地解析執(zhí)行,一毫秒緊接著一毫秒,從上至下地執(zhí)行,這稱之為同步。但如果我們想讓后臺的程序不等前面的程序執(zhí)行,就執(zhí)行呢,于是就有了異步的概念。
    2010-06-06
  • js實(shí)現(xiàn)iframe自動自適應(yīng)高度的方法

    js實(shí)現(xiàn)iframe自動自適應(yīng)高度的方法

    這篇文章主要介紹了js實(shí)現(xiàn)iframe自動自適應(yīng)高度的方法,涉及javascript操作iframe框架的技巧,非常具有實(shí)用價值,需要的朋友可以參考下
    2015-02-02
  • Yii2使用Bootbox插件實(shí)現(xiàn)自定義彈窗

    Yii2使用Bootbox插件實(shí)現(xiàn)自定義彈窗

    Bootbox.js 是一個小型的 JavaScript 庫用來創(chuàng)建簡單的可編程對話框,基于 Twitter 的 Bootstrap 開發(fā)。今天我們就來研究下,如何使用bootbox插件來實(shí)現(xiàn)自定義彈窗。
    2015-04-04
  • Javascript中for循環(huán)語句的幾種寫法總結(jié)對比

    Javascript中for循環(huán)語句的幾種寫法總結(jié)對比

    如果您希望一遍又一遍地運(yùn)行相同的代碼,并且每次的值都不同,那么使用循環(huán)是很方便的,javascript中for循環(huán)也是非常常用的,下面這篇文章主要介紹了Javascript中for循環(huán)的幾種寫法,需要的朋友可以參考借鑒,一起來看看吧。
    2017-01-01

最新評論