【发布时间】:2013-11-29 12:42:01
【问题描述】:
我有一个典型的 WCF 4.0 服务,它使用 wsHttpBinding 和 transactionFlow="true" 设置:
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
[FaultContract(typeof(Invalid))]
void DoWork();
这是我的服务器端实现:
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single,
TransactionIsolationLevel = IsolationLevel.Serializable,
TransactionTimeout = "00:00:15",
ReleaseServiceInstanceOnTransactionComplete = false
)]
public class MyService: IMyService {
[OperationBehavior(TransactionScopeRequired = false)]
public void DoWork() {
if (System.Transactions.Transaction.Current == null)
Trace.TraceInformation("WTF?!");
}
}
和客户端调用:
channel.DoWork(); // `Transaction.Current` is null at server-side as expected
using (var tx = new TransactionScope()) {
channel.DoWork(); // Transaction.Current is still null at server-side! :(
// .......
}
当我将 TransactionScopeRequired 更改为 true 时,我在服务器端得到了预期的分布式事务,但现在即使在没有外部范围的情况下调用也得到了它:
channel.DoWork(); // Transaction.Current is not null
最烦人的是,如果我返回Invalid 错误,它会回滚我的任何内部已完成 范围!这意味着尽管TransactionFlowOption.Allowed,在调用我的服务时我不得不始终使用显式事务范围。这是为什么呢?
我尝试将TransactionAutoComplete = false 添加到OperationBehavior 声明以希望解决问题,但得到了
System.InvalidOperationException: 合约上的操作“创建” 'IUserIdentityStore' 配置为 TransactionAutoComplete 设置为 false 并且 ConcurrencyMode 未设置为 Single。 TransactionAutoComplete 设置为 false 需要 ConcurrencyMode.Single。
这太荒谬了。
换句话说 - 当我返回声明的错误时,如何获得可选的事务流行为并且没有自动回滚?
【问题讨论】:
标签: c# .net web-services wcf transactions