【问题标题】:Passing TransactionScope to tasks created by Parallel.Invoke将 TransactionScope 传递给 Parallel.Invoke 创建的任务
【发布时间】:2011-09-02 02:51:20
【问题描述】:

我希望并行运行的TxJobs 从此父事务创建范围。我该如何进行这项工作?

using (var tx = TransactionScope()) {
    Parallel.Invoke(TxJob1, TxJob2) ;
    tx.Complete();
}

我传入了DependentClone

using (var tx = new TransactionScope()) {
    var dtx1 = Transaction.Current.DependentClone(
        DependentCloneOption.RollbackIfNotComplete) ;
    var dtx2 = Transaction.Current.DependentClone(
        DependentCloneOption.RollbackIfNotComplete) ;
    Parallel.Invoke(() => TxJob1(dtx1), () => TxJob2(dtx2)) ;
    tx.Complete();
}

TxJob1TxJob2 方法中,如果我只在DependentClones 上调用Complete,它就可以工作。但是,如果我从克隆创建一个范围,我会得到一个 TransactionAbortedException

void TxJob1(Transaction dt) {
    using (var tx = new TransactionScope(dt)) {
        Console.WriteLine(dtx.TransactionInformation.LocalIdentifier);
        tx.Complete();
    }
}

在 main 方法中调用 Complete 会引发异常,而不是在 TxJobs 中。为什么会失败?

[edit] 如果我在 TxJobs 的 DependentTransaction 上显式调用 Complete,那么它可以工作。如果我不在 TxJobs 中的新 TransactionScope 上调用 Complete(触发回滚),则父事务将失败。看起来我必须在两个 Transaction 对象上调用 Complete 。

【问题讨论】:

  • 您是否尝试过使用DependentCloneOption.BlockCommitUntilComplete 选项?即使Parallel.Invoke 将阻塞直到所有并行任务完成,你真的希望父Transaction 等待子完成,如果Complete 在子之前调用父(这是DependentCloneOption.RollbackIfNotComplete 所做的)。
  • @casperOne: 是的,在主方法调用Complete() 时使用BlockCommitUntilComplete 代码块,一段时间后超时并抛出TransactionAbortedException

标签: c# .net transactions transactionscope task-parallel-library


【解决方案1】:

看起来我必须在依赖克隆和 TransactionScope 上调用 Complete。 MS 在他们的 sample code 中也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 2015-04-16
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多