跨鏈碼和通道進行單元更新

您可以使用單元交易,以單元方式跨通道和鏈碼完成多個交易。

單元交易是所有成功或無成功之一系列不可分割的資料作業。

單元交易在將多個鏈碼部署到個別通道的複雜情況下很有用。即使發生網路或系統故障,您也可以使用單元交易在執行多個區塊鏈交易時維持資料一致性。Oracle Blockchain Platform 使用雙階段確認通訊協定支援單元交易,其中每個資料作業準備的初始階段,接著是實際確認每個資料作業的階段。

單元交易在應用程式層次運作。一般而言,您不需要變更現有的鏈碼邏輯來支援單元交易。因為單元交易架構新增一或多個其他引數,請確定任何現有的鏈碼不會對鏈碼方法中傳送的引數數目執行嚴格檢查。下列 REST API 端點支援單元交易:
  • restproxy/api/v2/atomicTransactions
REST API 端點會依照您的鏈碼所定義來準備交易,然後使用內建鏈碼函數來確認所有交易,或者如果在準備階段期間發生任何錯誤,則倒回所有交易。如需有關用於實行單元交易之 REST 端點的詳細資訊,請參閱單元交易 REST 端點

每個單元交易由兩個或多個區塊鏈交易組成。原子交易的結果 (returnCode 值) 為 SuccessFailure。在單元交易中,每個要求的區塊鏈交易都會分割為兩個不同的作業:準備階段,然後是確認階段或倒回階段。

  • 在準備階段中,每筆交易都會如常背書,但不會完成,會暫存變更並鎖定值,以防止其他交易修改暫存值。
  • 如果每個區塊鏈交易的準備階段都成功,則會使用內建的鏈碼來背書並確認交易。先前鎖定的值會解除鎖定,而單元交易的結果為 Success
  • 如果任何區塊鏈交易的準備階段失敗,則所有其他成功準備階段的交易都會使用內建的鏈碼再次倒回。系統會移除暫存的變更,並解除鎖定先前鎖定的值。原子交易的結果為 Failure
因為單元交易的運作方式是鎖定金鑰,所以如果其他交易嘗試修改由目前準備之作用中單元交易所鎖定的金鑰,您可能會收到 Two_Phase_Commit_Lock 錯誤。這可能發生在下列兩種情況之一:
  • 單元交易仍在準備階段,而不同的交易會嘗試修改已準備交易鎖定的金鑰。在此情況下,系統依設計運作。如果發生此錯誤,請重試第二個交易。這類似於應用程式如何處理虛擬在製品讀取錯誤或多重版本並行控制 (MVCC) 錯誤。
  • 由單元交易傳回的 GlobalStatus 值是 HeuristicOutcome。在此情況下,因為其中一個確認作業失敗,所以已取消單元交易作業。這很少發生,可能需要手動解決。試探結果的一個副作用是,某些索引鍵可能會被無法確認或倒回的交易鎖定。在此情況下,請使用下列 REST API 端點解除鎖定單元交易:
    • restproxy/api/v2/atomicTransactions/{globalTransactionId}
    如需有關用來解除鎖定單元交易之 REST 端點的詳細資訊,請參閱解除鎖定單元交易

案例:使用樣本瀏覽單元交易

請參考下列範例,其中使用 Oracle Blockchain Platform 、Balance Transfer 和 Marbles 隨附的兩個範例鏈碼。「餘額拋轉」範例代表具有在帳戶餘額之間拋轉資金能力的兩方。「馬鈴薯」範例可讓您建立馬鈴薯並在擁有者之間交換。您可以使用個別 (非單元) 交易來購買大理石,方法是交換「餘額轉移」鏈碼中的資金,以及變更 Marble 在 Marbles 鏈碼中的擁有權。不過,如果其中一個交易發生錯誤,分類帳可能會處於不一致的狀態:資金已移轉但未移轉大理石或大理石已移轉但未付款。

在此情況下,您可以將現有的鏈碼與支援單元交易的 REST API 端點搭配使用。資金交換與轉讓大理石的所有權都必須成功或同時失敗。如果任一交易發生錯誤,就不會確認任何交易。若要探索此案例,請完成下列步驟:

  1. 在不同管道上安裝「餘額移轉」與「圈存」樣本。如需有關安裝範例的詳細資訊,請參閱使用範例探索 Oracle Blockchain Platform
  2. 在 Marbles 範例中,呼叫 Create a new marble 動作,為各種大理石擁有者建立一些大理石。
  3. 使用 Invoke Atomic Transaction REST 端點完成可同時呼叫「大理石」和「餘額拋轉」樣本的單元交易。

例如,下列交易會將名為 marble1 的大理石傳輸至 Tom,並將 50 枚硬幣從帳戶 a 傳送至帳戶 b

{
 "transactions": [
   {"chaincode":"obcs-marbles","args":["transferMarble", "marble1", "tom"],"timeout":0, "channel":"goods"},
   {"chaincode":"obcs-example02","args":["invoke", "a", "b", "50"],"timeout":0, "channel":"wallet"}
 ],
 "isolationLevel": "serializable",
 "prepareTimeout": 10000,
 "sync": true
}

在前一個交易中,如果兩個交易都在準備階段成功,則兩個交易都會確認至分類帳。如果其中一個交易發生錯誤,則在第二個階段中不會確認任何交易。而是會倒回這兩個交易。例如,如果帳戶 a 中少於 50 枚硬幣,則不會從帳戶收取任何金錢,也不會將大理石轉移到 Tom。

Marble 範例有已知的問題,而 Marble 擁有者欄位的預設值。如需詳細資訊,請參閱:Oracle Blockchain Platform 已知問題