在連鎖經營代碼與通路進行單元更新
您可以使用單元交易,以原子方式跨通道和鏈碼完成多個交易。
單元交易是一系列無法分割的資料作業,不論是成功或完全不成功。
在將多個鏈碼部署到個別通道的複雜情況下,單元交易非常有用。即使發生網路或系統故障,您也可以使用單元交易在執行多個區塊鏈交易時維持資料一致性。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 隨附的兩個範例鏈碼。「餘額拋轉」範例代表具有在科目餘額之間移轉資金能力的雙方。Marbles 範例可讓您建立圈,並在擁有者之間交換它們。您可以使用個別 (非單元) 交易,透過在「餘額轉移」鏈碼中交換資金並變更 Marble 鏈碼中大理石的所有權來購買大理石。不過,如果其中一個交易發生錯誤,分類帳可能會處於不一致的狀態:資金已拋轉,但未拋轉大理石或大理石已拋轉,但未支付。
在此案例中,您可以將現有的鏈碼與支援單元交易的 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。
大理石擁有者欄位的預設值為已知問題。如需詳細資訊,請參閱:Oracle Blockchain Platform 的已知問題。