我可以阻止WCF在抛出故障时回滚事务吗?
考虑以下参与分布式事务的 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() {
//
// ...
//
}
}
客户端实现片段:
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 another transaction? 重复,但已接受的答案是我不满意 - 所有操作都发生在同一事务范围内很重要。
Consider the following WCF service which participates in a distributed transaction. The normal behavior of WCF is to roll back the transaction if any fault occurs. Is there any way to override that behavior?
Service contract:
[ServiceContract]
public interface ITestService {
[OperationContract]
[FaultContract(typeof(TestServiceFault))]
void ThrowError();
[OperationContract]
void DoSomething();
[OperationContract]
void DoSomethingElse();
}
[DataContract]
public class TestServiceFault{}
Service implementation:
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() {
//
// ...
//
}
}
Client implementation snippet:
using(new TransactionScope()) {
testServiceClient.DoSomething();
try {
testServiceClient.ThrowError();
} catch(FaultException<TestServiceFault>) {}
testServiceClient.DoSomethingElse();
}
When the FaultException is thrown from ThrowError(), WCF rolls back the distributed transaction which includes the work done by DoSomething(). Then, the client call to DoSomethingElse() fails with the message The flowed transaction could not be unmarshaled. The following exception occurred: The transaction has already been implicitly or explicitly committed or aborted.
In my particular scenario this behavior is undesirable. I'd like to catch the exception on the client side and continue about my business. If any exceptions occur that I don't catch, the client will be roll back the transaction.
Note: This question is a duplicate of How to handle a FaultException in WCF without aborting the whole transaction?, but the accepted answer there isn't satisfactory to me - it's important that all of the operations happen within the same transaction scope.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,你可以尝试在服务端设置 TransactionAutoComplete=false,
然后使用 SetTransactionComplete() 来防止异常回滚您的工作。
well, you could try setting the TransactionAutoComplete=false on the service side,
and then use SetTransactionComplete() to prevent the exception from rolling your work back.