文件首頁
MySQL NDB Cluster API 開發人員指南
相關文件 下載本手冊
PDF (US Ltr) - 3.6Mb
PDF (A4) - 3.6Mb


2.4.1 處理 NDB API 錯誤

摘要

本節說明如何偵測 NDB API 錯誤並將其對應至特定操作。

NDB API 錯誤可以透過以下兩種方式產生

  • 定義操作時

  • 執行操作時

操作定義期間引發的錯誤。在操作定義期間產生的錯誤會導致所呼叫方法傳回失敗的回傳碼。實際的錯誤可以透過檢查相關的 NdbOperation 物件或操作的 NdbTransaction 物件來判斷。

操作執行期間引發的錯誤。執行操作期間發生的錯誤會導致它們所屬的交易中止,除非操作設定了 AO_IgnoreError 中止選項。

預設情況下,讀取操作會使用 AO_IgnoreError 執行,而寫入操作則會使用 AbortOnError 執行,但使用者可以覆寫此行為。當執行期間發生錯誤導致交易中止時,execute() 方法會傳回失敗的回傳碼。如果因為在操作中設定 AO_IgnoreError 而忽略了錯誤,execute() 方法會傳回成功碼,並且使用者必須使用 NdbOperation::getNdbError() 檢查所有操作是否失敗。因此,即使 execute() 傳回成功,通常也應檢查 getNdbError() 的傳回值。如果用戶端應用程式在執行期間沒有追蹤 NdbOperation 物件,則可以使用 NdbTransaction::getNextCompletedOperation() 來逐一查看它們。

您也應該知道,使用 NdbBlob 可能會導致額外的操作新增至執行的批次中。這表示,當使用 getNextCompletedOperation() 逐一查看已完成的操作時,您可能會遇到與 NdbBlob 物件相關的操作,這些操作並非由您的應用程式所定義。

注意

LockModeCommittedRead 的讀取不能為 AbortOnError。在這種情況下,它永遠是 IgnoreError

在所有發生特定於操作的錯誤的情況下,會將針對操作和相關交易物件標記執行錯誤。如果單一 NdbTransaction::execute() 呼叫中存在多個操作錯誤,這是由於操作批次處理和使用 AO_IgnoreError 所造成,則只會針對 NdbTransaction 物件標記第一個錯誤。其餘錯誤只會記錄在對應的 NdbOperation 物件中。

執行期間也可能發生錯誤(例如資料節點故障),這些錯誤會針對交易物件標記,但不會針對基礎操作物件標記。這是因為這些錯誤適用於整個交易,而不適用於交易內的個別操作。

因此,應用程式應該使用 NdbTransaction::getNdbError() 作為判斷 NdbTransaction::execute() 呼叫是否失敗的第一種方法。如果執行的操作批次中包含設定了 AO_IgnoreError 中止選項的操作,則可能有多個失敗,應該使用 NdbOperation::getNdbError() 個別檢查已完成的操作是否有錯誤。

掃描與 BLOB 方法中的隱含 NdbTransaction::execute() 呼叫。掃描操作的執行方式與其他操作相同,並且在 NdbScanOperation::nextResult() 方法中也有隱含的 execute() 呼叫。當 NdbScanOperation::nextResult() 指示失敗時(也就是說,如果方法傳回 -1),應該檢查交易物件是否有錯誤。NdbScanOperation 也可能包含錯誤,但前提是該錯誤不是特定於操作的錯誤。

某些 blob 操作方法也有隱含的內部 execute() 呼叫,因此可能會在這些點發生操作執行失敗。以下 NdbBlob 方法可以產生隱含的 execute() 呼叫;這表示如果它們傳回錯誤碼,也需要透過 NdbTransaction::getNdbError() 檢查 NdbTransaction 物件是否有錯誤

  • setNull()

  • truncate()

  • readData()

  • writeData()

摘要。一般而言,當呼叫下列任何方法時,可能會在執行期間發生錯誤(導致傳回失敗的回傳碼)

如果發生這種情況,應呼叫 NdbTransaction::getNdbError() 方法來識別第一個發生的錯誤。當操作被批次處理,且批次中有 IgnoreError 操作時,交易中可能有多個操作發生錯誤。可以使用 NdbTransaction::getNextCompletedOperation() 來迭代已完成操作的集合,並為每個操作呼叫 NdbOperation::getNdbError() 來找到這些錯誤。

當在要執行的批次操作中的任何操作設定了 IgnoreError 時,即使實際上發生了錯誤,NdbTransaction::execute() 方法也會指示成功,只要這些錯誤中沒有任何一個導致交易中止。要確定是否出現了任何被忽略的錯誤,應使用 NdbTransaction::getNdbError() 來檢查交易錯誤狀態。只有在它指示成功時,才能確定沒有發生任何錯誤。如果此方法返回錯誤碼,且操作被批次處理,則應迭代所有已完成的操作,以找到所有具有被忽略錯誤的操作。

範例(虛擬碼)。 我們首先執行一個可能包含批次操作,以及混合使用 AO_IgnoreErrorAbortOnError 中止選項的交易。

int execResult= NdbTransaction.execute(args);
注意

關於 args 的數量和允許值,請參閱 NdbTransaction::execute()

接下來,由於 AO_IgnoreError 操作上的錯誤不會影響 execResult,也就是 execute() 返回的值,因此我們檢查交易中的錯誤。

NdbError err= NdbTransaction.getNdbError();

if (err.code != 0)
{

錯誤碼的非零值表示交易中發生了錯誤。這可能是由於以下任何一種情況造成的:

  • 交易範圍內的錯誤,例如導致交易中止的資料節點故障。

  • 單一操作特定的錯誤,例如導致交易中止的約束違規。

  • 單一操作特定的被忽略錯誤,例如找不到資料,但未導致交易中止。

  • 多個操作特定的被忽略錯誤中的第一個,例如批次處理時找不到資料,但未導致交易中止。

  • 在中止操作錯誤(交易中止)之前,多個操作特定的被忽略錯誤中的第一個,例如找不到資料(在批次處理時)。

   if (execResult != 0)
   {

交易已被中止。在這種情況下,處理錯誤的建議策略是測試交易錯誤狀態,並根據其值採取適當的行動。

      switch (err.status)
      {
        case value1:
          //  statement block handling value1 ...
        case value2:
          //  statement block handling value2 ...
          //  (etc. ...)
        case valueN:
          //  statement block handling valueN ...
      }

由於交易已中止,因此通常僅為了報告目的,才需要迭代已完成的操作(如果有的話),並找出每個操作引發的錯誤。

   }
   else
   {

交易本身未中止,但必定存在一個或多個被忽略的錯誤。在這種情況下,您應迭代這些操作以確定發生了什麼,並相應地處理原因。

   }
}

處理返回 -1NdbScanOperation::nextResult(),表示操作失敗(省略操作成功的情況)。

int nextrc= NdbScanOperation.nextResult(args);
注意

關於 args 的數量和允許值,請參閱 NdbScanOperation::nextResult()

if (nextrc == -1)
{

首先,您應該檢查 NdbScanOperation 物件中是否有任何錯誤。

  NdbError err= NdbScanOperation.getNdbError();

  if (err.code == 0)
  {

在掃描操作中未發現錯誤;該錯誤必定屬於整個交易。

  }
    err= NdbTransaction.getNdbError();

現在您可以根據錯誤狀態處理錯誤。

    switch (err.status)
    {
      case value1:
        //  statement block handling value1 ...
      case value2:
        //  statement block handling value2 ...
        //  (etc. ...)
      case valueN:
        //  statement block handling valueN ...
    }
}

有關 NDB API 錯誤分類和狀態碼的資訊,請參閱第 2.4.4 節,「NDB 錯誤分類」。儘管您不應在 NDB API 應用程式中依賴特定的錯誤碼或訊息文字(因為錯誤碼和訊息都會隨著時間而變更),但檢查錯誤碼和訊息有助於確定特定失敗發生的原因。有關這些的更多資訊,請參閱第 2.4.2 節,「NDB 錯誤碼:依類型」。有關 NdbError 以及可以從 NdbError 物件獲得的資訊類型,請參閱第 2.3.15 節,「NdbError 結構」