【发布时间】:2019-01-21 16:45:49
【问题描述】:
在 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 可能会成功处理事务 2,但事务 1 可能会因双花问题公证而失败。在这种情况下,第二个链将被不正确地更新。
使用vaultTrack 会更安全,因为事务 1 会成功,但无法保证事务 2 最终会完成。
【问题讨论】:
-
您似乎想要一个 Atomic Tx。如果是这样,在 Corda 中,Tx 是原子的。因此,任何必须是原子的都将成为单个 Tx 的一部分。您需要做的是制作一个 Tx。将您想要的所有更改添加到其中,即输入和输出状态,然后提交该 Tx。
-
根据乔尔的回答,您所说的可能是可能的。如果我的问题中的响应者被转换为发起者并将客户数据发送给他们,他们可以创建一个具有两个输出的 tx:1 是共享的客户数据(两个参与者),1 是他们自己的私有链(发起者作为参与者) .
标签: corda