0

我有以下情况,使用 C# 和 .NET 4.0。

我需要控制当我加载一组寄存器时,其他用户不能向该组添加一个新的,直到第一个用户没有完成对这些数据的处理。这是因为当一个用户添加一个新的寄存器时,它的数据取决于同一组的所有寄存器的信息。

一个简单的例子(愚蠢的例子,实际情况要复杂一些)。我有一个整数组。我想在我的数据寄存器中有一个指向组的最大 int 的字段。

Group: (IDGRoup, Name, description...)

Data: (IDData, IDGroup, IDMaxData,...)

如果我有两个用户尝试将新的 int 添加到组中,则过程如下:

1.- 加载组中的所有号码。

2.- 搜索最大数量

3.- 使用最大数字的 ID 设置 IDMaxData。

4.- 保存信息。

问题是如果两个用户同时加载,并尝试添加一个新的int,如果其中一个用户会添加新的组的最大数量,另一个用户无法将正确的ID设置为最大数量,因为他没有加载新的最大数量。因此信息不连贯,因为该用户将 IDMaxData 设置为旧的最大数。

如何保证数据的一致性?

我正在考虑使用交易。

1.- 从组中加载寄存器,其中 ID 是我想要的组的 ID。如果我使用具有可序列化隔离级别的事务,则在我加载组的寄存器的那一刻,第二个用户被阻止,因为他无法加载寄存器。所以如果第二个用户不能加载组表的寄存器,他就不能添加一个新的寄存器。

2.- 第一个寄存器可以加载数据表中的所有 int。他可以确定所有寄存器都存在,因为第二个用户无法添加新寄存器(他正在等待),因此他可以将 IDMaxData 设置为正确的保修数。

3.- 保存和发布数据。

第二个用户,他正在等待,不能从组表中加载寄存器,并阻止其他用户。完成工作并释放寄存器。

我怀疑这是否是一个好的解决方案。我能看到的唯一问题是我阻塞了 Group 表的寄存器,所以如果有人想更新它的信息,必须等到寄存器释放。但这是一个小问题,因为这个表的信息不会更新。

还有其他选择吗?

谢谢。

4

2 回答 2

1

您正在描述严格锁相技术,在该技术中,在提交最后一个 trxn 之前不允许开始任何事务。但我们也有其他技术。使用简单的锁相。

before any write the trxn must perform the read.
the trxn must acquire the read or write lock before performing any change on data item.
no two trxn can take write lock on same item. 

您还可以使用时间戳排序(TO)技术。

有关更多信息,请查看此 ppt ->并发控制

于 2013-01-22T19:59:02.697 回答
1

正如Arpit的并发控制链接所说,隔离级别Serializable可以避免这个Phantom Read问题。因此,它确实是Serializable针对您的问题的隔离级别的解决方案。但是隔离级别越高,并发的效率就越低。如何将最大 int 存储到全局静态属性?它基于db进行初始化,并在应用程序关闭时存储回db。并且在读取或更新时需要对全局静态属性应用锁。

于 2013-01-23T03:14:38.823 回答