跨鏈碼和通路進行單元更新
您可以使用單元交易,以單元方式跨通路和鏈碼完成多個交易。
單元交易是一系列不可分割的資料作業,這些作業成功或完全不成功。
單元交易在將多個鏈碼部署到個別通道的複雜情況下非常有用。即使發生網路或系統故障,您也可以在執行多個區塊鏈交易時使用單元交易來維持資料一致性。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 隨附的兩個範例鏈碼:餘額轉移和大理石。「餘額拋轉」樣本代表兩方可在帳戶餘額之間拋轉資金。Marble 樣本讓您可以建立圈子並在擁有者間交換 。您可以使用個別 (非單元) 交易,透過在餘額移轉鏈碼中交換資金,以及變更大理石鏈碼中的擁有權,來購買大理石。不過,如果其中一個交易發生錯誤,則分類帳可能會處於不一致的狀態:已拋轉資金,但未拋轉大理石,或大理石已拋轉但未付。
在此案例中,您可以將現有的鏈碼與支援單元交易的 REST API 端點搭配使用。資金交換與大理石所有權移轉必須成功或兩者皆失敗。如果任一交易發生錯誤,則不會確認交易。若要瀏覽此案例,請完成下列步驟:
- 在不同通路上安裝「餘額移轉」與「大理石」樣本。如需有關安裝範例的詳細資訊,請參閱使用範例探索 Oracle Blockchain Platform 。
- 在「大理石」範例中,呼叫
Create a new marble動作,為各種大理石擁有者建立多個大理石。 - 使用
Invoke Atomic TransactionREST 端點來完成同時呼叫 Marble 與 Balance Transfer 樣本的單元交易。
例如,下列交易會將名為 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。