1

我正在开发 WCF 服务,以帮助我们的新代码与旧系统互操作。过程是这样的:

  1. 客户端通过对遗留系统的请求调用服务。
  2. 服务将请求写入数据库。
  3. 遗留系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以表示结果已准备好)。
  4. 客户端通过调用第二个服务方法来检索结果,该方法会轮询数据库,直到设置就绪标志。
  5. 就在返回结果之前,服务将状态标志更新为client has results,以便可以删除相关的 DB 行。

我担心的是最后一步的比赛条件。我可以看到这种情况发生:

  1. 服务向客户端更新状态有结果
  2. 客户端等待服务轮询数据库后超时。
  3. 服务尝试返回结果。欢闹随之而来。

解决此问题的一种方法是使用三个服务调用而不是两个:第二个调用检索结果,最后一个调用是客户端明确确认它拥有它们。我想知道是否有一种方法不会将这种额外的“协议”负担强加给客户端。

我已经简要地研究了在 WCF 中使用事务,听起来他们可能能够做我需要的事情。客户端(可选)启动一个事务,将其流向服务,如果它存在则使用它,并在完成时提交它。这似乎隐含地进行了“第三次调用”。

这个想法有什么好处吗?你能看出什么缺点吗?还有其他我可以探索的途径吗?

4

2 回答 2

1

为什么不通过这样做来减少客户端超时的可能性:

  1. 客户端调用服务并请求遗留系统。
  2. 服务将请求写入数据库。
  3. 遗留系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以表示结果已准备好)。
  4. 客户端调用服务来确定结果是否准备就绪。注意。没有轮询:只返回一个立即是或否。
  5. 如果结果尚未准备好,客户端稍等片刻,然后返回步骤 4。
  6. 如果结果已准备就绪,请调用服务以检索结果。该服务可以在此时将状态更新为“客户有结果”

通过这样做,客户端将不会等待第 4 步中的服务调用返回很长一段时间,并且超时的可能性应该是最小的。

但是,您永远无法100% 确定客户已收到结果,除非客户发出最终的服务电话来说明这一点。(例如,如果客户端在发出最后一个请求后死了怎么办?)

于 2011-07-01T10:18:39.260 回答
1

使用事务流是可能的,但在轮询场景中(在每个轮询调用中)流动事务是糟糕的架构。您通常需要的是实际读取操作的事务流,其中服务修改记录并将数据返回给客户端。客户端将提交事务,并将提交由服务执行的更改。

使用事务处理对您的服务和客户端提出了一些额外的要求。

另一种方法可以是事务性 MSMQ:

  1. 客户端通过对遗留系统的请求调用服务 = 客户端向服务的队列发送消息
  2. 服务将请求写入数据库 = 服务处理其队列中的消息
  3. 遗留系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以表示结果已准备好)。
  4. 服务轮询数据库并将消息放置到正确的客户端队列中。放置消息和修改数据库记录在事务中运行
  5. 客户端处理传入消息

Transactional queue allows transactional reading (the message is removed from the queue only if transaction is committed) and writing (the message is added to the queue only if transactions is committed). That will allow deleting records before the client reads the message because the message will remain in the queue until he successfully reads it (or until it timeouts and even after that it can be passed to some error queues).

In both cases you should think about clients who will consume the service. Transaction flowing can be interoperable but not every web service stack supports it. MSMQ is not interoperable.

于 2011-07-01T11:39:32.670 回答