WCF InstanceContextMode:此方案中的Per Call vs. Single

时间:2011-07-15 14:16:01

标签: wcf

我想避免在我的系统中生成重复的数字。

CreateNextNumber()将:

  1. 查找最后创建的号码。
  2. 将值增加一个。
  3. 使用新号码更新数据库中的值。
  4. 我想避免两个客户端同时调用此方法。我担心他们会拉出相同的最后一个数字,增加一个,然后返回两个客户的重复数字。

    问题:

    1. 我需要在这里使用单一模式吗?如果可能,我宁愿使用Per Call。
    2. 默认并发模式是单一的。我不明白Per Call如何创建多个实例,但是只有一个线程。这是否意味着即使创建了多个实例,一次只有一个客户端可以在其实例中调用方法?

3 个答案:

答案 0 :(得分:2)

如果您使用InstanceContextMode.Single和ConcurrentcyMode.Single,您的服务将一次处理一个请求,因此会为您提供此功能 - 但是,在数据库中可以更好地处理此问题

几个选项:

  1. 使需要唯一编号的字段成为标识列,数据库将确保没有重复值
  2. 在使用隔离级别RepeatableRead的存储过程中包含控制值的递增,并在事务中读取,递增和写入
  3. 对于您的问题,您可能会在instancing and concurrency上找到我的博客文章

答案 1 :(得分:0)

单个实例不会停止服务同时处理请求,我不这么认为。您需要一个服务器端同步机制,例如Mutex,以便尝试获取此数字的所有代码首先锁定。实际上,您可能会在服务代码中使用静态锁定对象,这可能比互斥锁更简单。

基本上,这不是WCF配置问题,这是一个更普遍的并发问题。

private static object ServiceLockingObject = new object();

lock (ServiceLockingObject)
{
   // Try to increment your number.
}

答案 2 :(得分:0)

不要打扰WCF设置,而是在数据库中生成唯一的数字。有关详细信息,请参阅my answer to this question。您尝试在WCF中执行的任何操作都会出现以下问题:

  • 如果有人在Web场中部署了多个服务实例,则每个实例都会生成冲突数字。
  • 如果在读取或写入表格期间出现数据库错误,则会出现问题。
  • 仅仅在单独的步骤中读取和写入表的行为将引入大量的并发问题。你真的想强制一个可序列化的表锁并让一切都在唯一的数字生成器上排队吗?
  • 如果您在服务代码中开始交易,则所有其他请求将在唯一号码表上阻止,因为它将成为长时间运行的交易的一部分。