【问题标题】:WCF basicHttpBinding: Rollback when reply to client failsWCF basicHttpBinding:回复客户端失败时回滚
【发布时间】:2012-02-15 14:48:14
【问题描述】:

我正在通过 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

【问题讨论】:

  • 要在 WCF 中进行事务,您需要 WS-Transaction。这不适用于 basicHttpBinding 端点。它需要 wsHttpBinding。更多详情请见this question
  • 为什么需要使用basiHttpBinding? wsHttpBinding 会给你这个。
  • 我没有尝试将事务 通过 WCF 传递给客户端,事务应该专门在服务器端,因此不使用像 WS-Transactions 这样的机制。跨度>
  • @JustinDearing:访问服务的客户端不支持wsHttpBinding。
  • 使用basicHttpBinding,无法知道客户端是否收到响应。

标签: wcf transactions basichttpbinding


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 我进一步澄清了这个问题。如果从客户端到服务器的回复消息传输失败,我只想回滚事务。客户端永远不会发挥作用,或者仅在客户端无法接收 TCP/IP 数据包时发挥作用。
  • 但是服务如何知道客户端是否收到了消息呢?它是否必须在第二次调用中通知服务,例如,传递一个事务 ID 的 Commit 方法,该事务 ID 是从对初始服务调用的响应中获得的...
  • 我明白您对 TCP/IP ACK 的看法,但您使用的是 HTTP,我认为 WCF 不会公开底层 TCP/IP。事实上,HTTP 不一定是基于 TCP/IP 的。任何可靠的运输都可以。这可能意味着严格遵守标准的实现不会暴露底层的有线协议。
  • 这可能是 WCF 实际上隐藏了是的情况;我正在对 WCF 代码进行一些研究,但尚未在源中找到实际通过传输层发送回复消息的位置。但从理论上讲,如果有可能进入那个地方,它就可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2023-03-03
相关资源
最近更新 更多