【发布时间】:2020-04-15 05:04:52
【问题描述】:
我想知道如何使用超级账本作曲家在超级账本结构中执行并发事务。 当我尝试同时针对同一资源提交两个事务时,我收到此错误:
尝试调用业务网络时出错。错误:对等方已拒绝事务 \'transaction-number\',代码为 MVCC_READ_CONFLICT
有谁知道是否存在避免这种情况的解决方法或设计模式?
【问题讨论】:
标签: hyperledger-fabric hyperledger-composer
我想知道如何使用超级账本作曲家在超级账本结构中执行并发事务。 当我尝试同时针对同一资源提交两个事务时,我收到此错误:
尝试调用业务网络时出错。错误:对等方已拒绝事务 \'transaction-number\',代码为 MVCC_READ_CONFLICT
有谁知道是否存在避免这种情况的解决方法或设计模式?
【问题讨论】:
标签: hyperledger-fabric hyperledger-composer
虽然我可能没有提供最好的解决方案,但我希望就这个问题分享一些想法和可能的解决方法。
首先让我们简要解释一下您收到此错误的原因。 Hyperledger Fabric 的底层数据库采用了类似 MVCC(多版本并发控制)的模型。例如,两个客户端尝试将版本 0 的资产更新为某个值。一个会成功(更新值并将 stateDB 中的版本号增加到 1),而另一个会由于版本不匹配而失败并出现此错误(MVCC_READ_CONFLICT)。
这里讨论的一个可能的解决方案 (https://medium.com/wearetheledger/hyperledger-fabric-concurrency-really-eccd901e4040) 是在业务逻辑和 Fabric SDK 之间自行实现一个 FIFO 队列。在这种情况下也可以添加重试逻辑。
另一种方法是使用增量概念。假设有一个值为 10 的资产 A(也许它代表账户余额)。该资产被多个并发交易频繁更新(例如在这组值 12 -> 19 -> 16 中更新),并且很容易触发上述错误。相反,我们将值存储为增量 (+2 -> +7 -> -3),最终汇总值在分类帐中将是相同的。但请记住,这个技巧可能不适合所有情况,在这个例子中,您可能还需要密切监控运行总额,以避免在您的帐户空缺时给钱。所以它在很大程度上取决于数据类型和用例。
更多信息可以看这个:https://github.com/hyperledger/fabric-samples/tree/release-1.1/high-throughput
【讨论】:
我最近遇到了这个问题,并通过创建一组调用异步函数的承诺来解决它,然后一次解决一个。
我的交易将 asset2Ids 和 asset3Ids 数组中的项目添加到 asset1 上的数组字段中。我的交易都作用于同一个资产,所以我收到了一个 MVCC_READ_CONFLICT 错误,因为读/写集在每个交易提交之前发生了变化。通过强制事务以同步方式解决,此冲突得到修复:
// Create a function array
let funcArray = [];
for (const i of asset2Ids) {
// Add this transaction to array of promises to be resolved
funcArray.push(()=>transactionFunctionThatAddsAsset2IdToAsset1(i).toPromise());
}
for (const j of asset3Ids) {
// Add this transaction to array of promises to be resolved
funcArray.push(()=>transactionFunctionThatAddsAsset3IdToAsset1(j).toPromise());
}
// Resolve all transaction promises against asset in a synchronous way
funcArray.reduce((p,fn) => p.then(fn), Promise.resolve());
【讨论】: