在Cordapp中,我希望在正常事务的一部分中更新第二个链。由于数据在具有不同参与者的两个单独状态中被跟踪,因此这需要在两个事务中完成。
为了讨论,我们有A和B两方。 A与B启动交易1。在收到交易1后,B方启动交易2以更新另一个状态。如何确保两个交易都成功完成?
有两种方法可以解决:
- 内联响应流程中启动交易2的
subFlow
。 - 使用
vaultTrack
来响应已提交的交易1并启动交易2的subFlow
。
以下是选项1的示例代码:
class CustomerIssueFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
override fun checkTransaction(stx: SignedTransaction) = requireThat {
val output = stx.tx.outputs.single().data
"This must be an CustomerState." using (output is CustomerState)
}
}
// signing transaction 1
val stx = subFlow(signTransactionFlow)
val customerState = stx.tx.outputs.single().data as CustomerState
// initiating transaction 2
subFlow(CustomerIssueOrUpdateFlow(customerState))
return stx
}
}
每种方法的利弊是什么?
我对选项1的担忧在于,单个流程中涉及的两个事务不是原子性的。其中一个事务可能会失败,而另一个成功,这将导致数据处于不一致的状态。例如:上面响应器中的subFlow
可能会成功地完成第二个事务,但第一个事务可能因双重支付问题的记账失败。在这种情况下,第二条链将被错误地更新。
使用vaultTrack
会更安全,因为第一个事务将会成功,但不能保证第二个事务最终会完成。