仅当客户端收到结果时,WCF服务才会写入日志

时间:2011-07-01 09:56:33

标签: wcf transactions race-condition distributed-transactions

我正在开发一个WCF服务,以帮助我们的新代码与遗留系统进行互操作。过程如下:

  1. 客户端通过遗留系统请求调用该服务。
  2. 服务将请求写入数据库。
  3. 传统系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以说明结果已准备好)。
  4. 客户端通过调用第二个服务方法来检索结果,该方法轮询数据库,直到设置就绪标志为止。
  5. 在返回结果之前,服务会将状态标志更新为客户端有结果,以便删除相关的数据库行。
  6. 我担心的是最后一步的竞争状况。我可以看到这种情况发生了:

    1. 客户端的服务更新状态具有结果
    2. 客户端在等待服务轮询数据库后超时。
    3. 服务尝试返回结果。随之欢闹。
    4. 解决此问题的一种方法是使用三个服务调用而不是两个:第二个调用检索结果,最后一个是客户端明确确认它有它们。我想知道是否有一种方法不会给客户带来额外的“协议”负担。

      我简要介绍了在WCF中使用事务,听起来他们可能能够做我需要的事情。客户端(可选)启动一个事务,将其传递给服务,如果它在那里使用它,并在完成后提交它。这似乎暗含着“第三次电话”。

      这个想法有什么优点吗?您可以看到任何缺点?我还有其他途径可以探索吗?

2 个答案:

答案 0 :(得分:1)

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

  1. 客户通过遗留系统请求呼叫服务。
  2. 服务将请求写入数据库。
  3. 传统系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以表示结果已准备就绪)。
  4. 客户端调用服务以查明结果是否已准备就绪。 NB。没有民意调查:只是立即返回是或否。
  5. 如果结果尚未就绪,客户端稍等一会然后返回步骤4.
  6. 如果结果已准备就绪,请调用服务以检索结果。该服务可以在此时将状态更新为“客户端有结果”
  7. 通过执行此操作,客户端将不会在步骤4中等待服务调用以长时间返回,并且超时的可能性应该最小。

    但是,除非客户进行最终服务电话,否则您永远不会<100>确定客户端已收到结果。 (例如,如果客户端在发出最后一个请求后死亡,该怎么办?)

答案 1 :(得分:1)

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

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

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

  1. 客户端使用遗留系统的请求调用服务=客户端向服务的队列发送消息
  2. 服务将请求写入database = service处理来自其队列的消息
  3. 传统系统服务在自己的时间从数据库请求并将结果写回数据库(更新状态标志以表示结果已准备就绪)。
  4. 服务轮询数据库并将消息放入正确的客户端队列。放置消息和修改数据库记录在事务
  5. 中运行
  6. 客户端处理传入消息
  7. 事务性队列允许事务性读取(仅在提交事务时才从队列中删除消息)和写入(仅在事务提交时才将消息添加到队列中)。这将允许在客户端读取消息之前删除记录,因为消息将保留在队列中,直到他成功读取它(或者直到它超时,甚至在它之后可以传递给某些错误队列)。

    在这两种情况下,您都应该考虑将使用该服务的客户。事务流可以互操作,但并非每个Web服务堆都支持它。 MSMQ不可互操作。