跨鏈碼和通道進行單元更新
您可以使用單元交易,以單元方式跨通道和鏈碼完成多個交易。
單元交易是所有成功或無成功之一系列不可分割的資料作業。
單元交易在將多個鏈碼部署到個別通道的複雜情況下很有用。即使發生網路或系統故障,您也可以使用單元交易在執行多個區塊鏈交易時維持資料一致性。Oracle Blockchain Platform 使用雙階段確認通訊協定支援單元交易,其中每個資料作業準備的初始階段,接著是實際確認每個資料作業的階段。
restproxy/api/v2/atomicTransactions
每個單元交易由兩個或多個區塊鏈交易組成。原子交易的結果 (returnCode
值) 為 Success
或 Failure
。在單元交易中,每個要求的區塊鏈交易都會分割為兩個不同的作業:準備階段,然後是確認階段或倒回階段。
- 在準備階段中,每筆交易都會如常背書,但不會完成,會暫存變更並鎖定值,以防止其他交易修改暫存值。
- 如果每個區塊鏈交易的準備階段都成功,則會使用內建的鏈碼來背書並確認交易。先前鎖定的值會解除鎖定,而單元交易的結果為
Success
。 - 如果任何區塊鏈交易的準備階段失敗,則所有其他成功準備階段的交易都會使用內建的鏈碼再次倒回。系統會移除暫存的變更,並解除鎖定先前鎖定的值。原子交易的結果為
Failure
。
- 單元交易仍在準備階段,而不同的交易會嘗試修改已準備交易鎖定的金鑰。在此情況下,系統依設計運作。如果發生此錯誤,請重試第二個交易。這類似於應用程式如何處理虛擬在製品讀取錯誤或多重版本並行控制 (MVCC) 錯誤。
- 由單元交易傳回的
GlobalStatus
值是HeuristicOutcome
。在此情況下,因為其中一個確認作業失敗,所以已取消單元交易作業。這很少發生,可能需要手動解決。試探結果的一個副作用是,某些索引鍵可能會被無法確認或倒回的交易鎖定。在此情況下,請使用下列 REST API 端點解除鎖定單元交易:restproxy/api/v2/atomicTransactions/{globalTransactionId}
案例:使用樣本瀏覽單元交易
請參考下列範例,其中使用 Oracle Blockchain Platform 、Balance Transfer 和 Marbles 隨附的兩個範例鏈碼。「餘額拋轉」範例代表具有在帳戶餘額之間拋轉資金能力的兩方。「馬鈴薯」範例可讓您建立馬鈴薯並在擁有者之間交換。您可以使用個別 (非單元) 交易來購買大理石,方法是交換「餘額轉移」鏈碼中的資金,以及變更 Marble 在 Marbles 鏈碼中的擁有權。不過,如果其中一個交易發生錯誤,分類帳可能會處於不一致的狀態:資金已移轉但未移轉大理石或大理石已移轉但未付款。
在此情況下,您可以將現有的鏈碼與支援單元交易的 REST API 端點搭配使用。資金交換與轉讓大理石的所有權都必須成功或同時失敗。如果任一交易發生錯誤,就不會確認任何交易。若要探索此案例,請完成下列步驟:
- 在不同管道上安裝「餘額移轉」與「圈存」樣本。如需有關安裝範例的詳細資訊,請參閱使用範例探索 Oracle Blockchain Platform 。
- 在 Marbles 範例中,呼叫
Create a new marble
動作,為各種大理石擁有者建立一些大理石。 - 使用
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 已知問題。