Wcf 为什么服务行为';ReleaseServiceInstanceOnTransactionComplete=false';与';并发模式。多个';启用事务时

Wcf 为什么服务行为';ReleaseServiceInstanceOnTransactionComplete=false';与';并发模式。多个';启用事务时,wcf,Wcf,我的一个WCF服务操作已启用事务- [OperationBehavior(TransactionScopeRequired = true)] public Car UpdateCar(Car c) { } 早些时候,我使用InstanceContextMode作为PerCall和ConcurrencyMode作为Multiple运行此服务,这导致了以下错误- System.ServiceModel.dll中发生类型为“System.InvalidOperationException”的未处理异

我的一个WCF服务操作已启用事务-

[OperationBehavior(TransactionScopeRequired = true)]
public Car UpdateCar(Car c)
{
}
早些时候,我使用InstanceContextMode作为PerCall和ConcurrencyMode作为Multiple运行此服务,这导致了以下错误-

System.ServiceModel.dll中发生类型为“System.InvalidOperationException”的未处理异常 其他信息:“InventoryManager”服务配置为ReleaseServiceInstanceOnTransactionComplete设置为true,但ConcurrencyMode未设置为Single。ReleaseServiceInstanceOnTransactionComplete需要使用ConcurrencyMode.Single

为了解决上面的错误,我将“ReleaseServiceInstanceOnTransactionComplete”设置为false,这样就成功了

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall
                 , ConcurrencyMode = ConcurrencyMode.Multiple
                 , ReleaseServiceInstanceOnTransactionComplete = false)]

请有人帮助理解如何使用“PerCall”和“Multiple”案例处理服务实例来解决此问题。如果我发布服务实例,WCF会考虑什么问题。

这些都是WCF设计师做出的纯粹的设计决策

在《编程WCF服务》一书中:

WCF架构师不信任开发人员在面对事务时正确管理其会话服务的状态。因此,他们决定将会话式事务服务视为每调用服务,以实施适当的状态感知编程模型

还有一个带有并发模式的Percall服务。多个当然没用。在服务加载时,WCF验证当ReleaseServiceOnTransactionComplete为true时,如果至少一个操作的TransactionScopeRequired为true,则ConcurrencyMode为ConcurrencyMode.Single。 这就是你正在观察的行为

设计者在让WCF处理事务并发性方面的决定可能是正确的。很难在服务中管理自己的并发性

例如,我有一个服务,它还充当另一个服务的客户机

将并发模式更改为多并发模式时,在尝试打开客户端连接时,服务有时会引发异常:

“System.InvalidOperationException:无法调用此频道,因为正在调用Open()。”


这是一种很难调试的bug,设计者想要避免(我认为)

这些纯粹是WCF设计者的设计决策

在《编程WCF服务》一书中:

WCF架构师不信任开发人员在面对事务时正确管理其会话服务的状态。因此,他们决定将会话式事务服务视为每调用服务,以实施适当的状态感知编程模型

还有一个带有并发模式的Percall服务。多个当然没用。在服务加载时,WCF验证当ReleaseServiceOnTransactionComplete为true时,如果至少一个操作的TransactionScopeRequired为true,则ConcurrencyMode为ConcurrencyMode.Single。 这就是你正在观察的行为

设计者在让WCF处理事务并发性方面的决定可能是正确的。很难在服务中管理自己的并发性

例如,我有一个服务,它还充当另一个服务的客户机

将并发模式更改为多并发模式时,在尝试打开客户端连接时,服务有时会引发异常:

“System.InvalidOperationException:无法调用此频道,因为正在调用Open()。”


这是一种难以调试的bug,设计者希望避免这种bug(我认为)

服务的默认实现是

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
如果在服务实现的任何操作上定义了TransactionScope:

[OperationBehavior(TransactionScopeRequired = true)]
public void Method() { }
默认服务实现将被删除到

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
此属性将阻止它并恢复您的PerSession语义:

[ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = false)]

请注意,如果您在其中一个操作上有会话式服务且至少有一个TransactionScopeRequired=True,则这是必需的。

服务的默认实现是

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
如果在服务实现的任何操作上定义了TransactionScope:

[OperationBehavior(TransactionScopeRequired = true)]
public void Method() { }
默认服务实现将被删除到

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
此属性将阻止它并恢复您的PerSession语义:

[ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = false)]
请注意,如果您在其中一个操作上有会话服务且至少有一个
TransactionScopeRequired=True
,则这是必需的