【问题标题】:Can I prevent WCF from rolling back the transaction when a fault is thrown?抛出错误时,我可以防止 WCF 回滚事务吗?
【发布时间】:2011-06-29 06:22:52
【问题描述】:

考虑以下参与分布式事务的 WCF 服务。 WCF 的正常行为是在发生任何故障时回滚事务。有没有办法覆盖这种行为?

服务合同:

[ServiceContract]
public interface ITestService {
    [OperationContract]
    [FaultContract(typeof(TestServiceFault))]
    void ThrowError();
    [OperationContract]
    void DoSomething();
    [OperationContract]
    void DoSomethingElse();
}

[DataContract]
public class TestServiceFault{}

服务实现:

class TestService : ITestService {
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void ThrowError() {
        throw new FaultException<TestServiceFault>(new TestServiceFault());
    }
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void DoSomething() {
        //
        // ...
        //
    }
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void DoSomethingElse() {
        //
        // ...
        //
    }
}

客户端实现sn-p:

using(new TransactionScope()) {
    testServiceClient.DoSomething();

    try {
        testServiceClient.ThrowError();
    } catch(FaultException<TestServiceFault>) {}

    testServiceClient.DoSomethingElse();
}

当 ThrowError() 抛出 FaultException 时,WCF 回滚分布式事务,其中包括 DoSomething() 完成的工作。然后,对 DoSomethingElse() 的客户端调用失败并显示消息 无法解组流的事务。发生以下异常:事务已被隐式或显式提交或中止。

在我的特定情况下,这种行为是不可取的。我想在客户端捕获异常并继续我的业务。如果发生任何我没有捕捉到的异常,客户端将回滚事务。

注意:这个问题与How to handle a FaultException in WCF without aborting the whole transaction? 重复,但那里接受的答案令我不满意——重要的是所有操作都发生在同一个事务范围内。

【问题讨论】:

  • 如果你只有一个事务范围,那么失败将导致整个事务回滚——毕竟这就是它的全部意义所在。如果您想要一个“孤立”的子事务,它可以失败而不影响整个事务,您需要使用其他问题中显示的方法。我没有看到任何其他方法 - 选择这两种解决方案中的任何一种 - 没有其他“神奇”方式......
  • 是的,我理解这种行为的意义,但我想说合同中定义的错误(或者可能是某个子集)不是失败。看起来这是不可能的。

标签: .net wcf distributed-transactions


【解决方案1】:

好吧,您可以尝试在服务端设置 TransactionAutoComplete=false, 然后使用 SetTransactionComplete() 来防止异常回滚您的工作。

【讨论】:

  • 行得通,谢谢!我想找到一个可以执行此操作的扩展点,以便将其作为一种行为应用到我的操作中。
  • 很高兴听到,将其应用为一种行为,也许您可​​以使用一些面向方面的框架,将 tran 完整应用于您指定的异常类型。 (可能在操作后步骤中)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 2010-12-14
  • 1970-01-01
相关资源
最近更新 更多