我遇到的问题是这样的:

我有一个包含以下字段的表(仅作为示例):

ID int
Value int

我有一个名为 IncreaseByFive() 的方法,它执行以下操作:

method IncreaseByFive(int ID)
{    
    int value = GetValueFromDB(ID);
    value = value + 5;
    SaveValueToDB(value, ID);    
}

我想要避免的是以下情况:

  1. 用户A调用方法并获取值(当前为5)
  2. 用户B调用方法并获取值(当前为5)
  3. 用户 A 的价值增加了​​ 5(现在为 10)
  4. 用户 B 将价值增加 5(现在为 10)
  5. 用户 A 保存值 (10)
  6. 用户 B 保存值 (10)

现在该记录的值为 10,而它本应为 15。

我想要强制的是以下内容:

  1. 用户A调用方法并获取值(当前为5)
  2. 用户 B 调用方法,但必须等待,因为 A 已经调用了该方法。(迪布斯!)
  3. 用户 A 增加值(现在为 10)
  4. 用户B仍在等待
  5. 用户 A 保存该值(记录值为 10)
  6. 用户 B 现在可以读取值 (10)
  7. 用户B增加值(15)
  8. 用户B保存该值

现在记录的值为 15,这就是我正在寻找的结果。

我过去使用静态类解决了这个问题,并对在该类的构造函数中创建的静态对象加了锁,从而通过一个静态方法集中所有工作,这迫使其他调用排队等待。但恐怕这不可扩展。

我还认为事务的最高隔离级别(可序列化)也不会起作用,因为它将允许在上面不需要的示例的步骤 2 中进行读取。

我想另一种解决方案是创建我自己的锁表并在那里记录锁,但这似乎不是必需的。

我正在使用 C# (3.5) 和 SQL Server 2008 开发这个项目。

蜂巢思维在想什么?

有帮助吗?

解决方案

也许我是 超过没有考虑到这一点,但是您不会包装整个逻辑块吗?

  • 读取值
  • 写入值

在数据库事务中 适当的水平?

SET TRANSACTION ISOLATION LEVEL
    { READ UNCOMMITTED
    | READ COMMITTED
    | REPEATABLE READ
    | SNAPSHOT
    | SERIALIZABLE
    }
[ ; ]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top