6

我通过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
4

1 回答 1

1

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

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

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

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

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

于 2012-02-21T20:16:03.507 回答