WCF basicHttpBinding:回复客户端失败时回滚

Gau*_*ssZ 6 wcf transactions basichttpbinding

我通过basicHttpBinding在数据库上执行多个操作来公开WCF服务.

我想保证,如果客户端没有收到回复,则回滚数据库操作(没有任何事务流通过WCF).例如,客户端调用在服务器上执行但在完成之前客户端崩溃的"DoX"方法.一旦无法将回复发送到客户端,就应该回滚数据库操作.

有没有办法做到这一点?[OperationBehavior(TransactionScopeRequired=true)]属性是否会以这种方式工作?是否有可能处理服务器端的通信错误?

更新1: 似乎[OperationBehavior(TransactionScopeRequired=true)]在将回复发送到客户端之前提交事务,因此如果客户端没有收到回复,则不能用于执行回滚.

更新2: 要再次明确说明,我不需要事务以任何方式与客户端进行交互.客户端既不知道事务,也不能取消或提交事务,任何事务都不应该通过绑定.如果传输通道无法将消息传递到接收客户端,那么我希望事务回滚的唯一位置是在服务器端.对于TCP/IP的情况,该信息应该随时可供服务器使用.(没有TCP数据包的ACK发送回客户端)

因此,服务器端的假设执行流程(请注意缺少客户端)应该是:

Receive client request

Start transaction

Execute all logic inside the service operation

Send reply back to client

if (reply.failedToReceive) { transaction.Rollback() } // due to a failing TCP/IP transmission
Run Code Online (Sandbox Code Playgroud)

Mik*_*win 1

这个问题没有简单的答案。您要求一种在 WS-* 中实现但使用基本 SOAP 完成的行为。我认为,如果您确实无法切换到 wsHttpBinding 或按照 @Trevor Pilley 的建议使用双工,那么您唯一的选择是尝试在您自己的基于基本 SOAP 的自定义协议中模仿 WS-Transaction 的行为。

您应该能够对完整的 WS-Transaction 规范进行一些简化,因为

  • 您可能只需要支持单个服务上的事务 - 您不会在多个独立服务上执行分布式事务
  • 您不需要同时支持短事务(WS-AtomicTransaction)和长时间运行的事务(WS-BusinessActivity),原子事务可能会做
  • 您不需要支持任何类型的可扩展性模型(WS-Coordination
  • 您不需要实现描述协议的发现/元数据模型(例如 WSDL),因为您可以将协议行为直接编码到客户端和服务中。

但是,您可能需要 WS-Coordination 和 WS-AtomicTransaction 的元素。无论如何,这都不是一项简单的任务,并且很容易错过一些微妙的事情,这些微妙的事情可能导致回滚不发生,或者(同样糟糕)由于在整个数据库上长期锁定而破坏服务的性能崩溃的客户。

就像我说的,这是一个复杂的行为,如果你不能使用现成的标准化协议,那么就没有简单的答案。