DataGrid - 防止对行的并发访问

时间:2010-02-14 21:40:39

标签: c# java

我需要编写一个简单的数据网格表单,允许用户编辑单元格 - 问题是不同的人可以在同一时间编辑它,因此并发性成为一个问题

我使用的是数据库支持的数据

我似乎有两个选择:

1)在允许编辑之前,继续轮询数据库并刷新数据网格中的数据 - 这意味着数据库的更新需要在编辑后进行,而不是允许编辑的优先方式,然后让用户查看然后提交。

2)允许脏编辑,然后阻止用户向数据库提交他们想要的更改

任何人都可以描述一个mechansim,允许用户同时编辑行,这将使实现变得容易吗?

编辑:我的问题是如何在C#中实现这一点 - 我添加了锁定列,但这仍然不够 - 如果usera尝试编辑row1并提交更改,则userB尝试编辑row1的旧版本,这将不会被捕获这是一个很大的问题

2 个答案:

答案 0 :(得分:4)

您有这些选项但不限于:

  

乐观并发 - 假设虽然可能存在并发性   不时发生冲突,广大   大多数时候这种冲突   不会出现;因此,如果发生冲突   确实出现了,只需告知用户   他们的改变无法保存   因为另一个用户修改了   相同的数据

     

悲观并发 - 假设并发冲突是   平凡而且用户不会   容忍被告知他们的变化   因为另一个用户没有保存   并发活动;因此,何时   一个用户开始更新记录,   锁定它,从而阻止任何其他   用户编辑或删除   记录直到用户提交他们的   修改

有关参考和详情,请参阅:


乐观并发

PeopleDataContext people = new PeopleDataContext();     
Person p = people.People.Single(person => person.ID == 1);     
p.IDRole = 2;

try
{ people.SubmitChanges(ConflictMode.ContinueOnConflict); }

catch (ChangeConflictException cce)
{ people.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges); }

悲观并发

PeopleDataContext people = new PeopleDataContext();

using (TransactionScope t = new TransactionScope())
{
   Person p = people.People.Single(person => person.ID == 1);

   p.LastName = "Pessimistic";
   p.FirstName = "Concurrency";    

   people.SubmitChanges();     
   t.Complete();
}

参考:


答案 1 :(得分:0)

实现乐观锁定的一种简单方法是向表中添加行版本列。 (如果您的数据库服务器支持它,请SQL Server 2005 and 2008 do。)

当用户加载记录进行编辑时,获取记录的行版本。

当用户尝试保存更新时,再次获取记录的行版本并将其与用户编辑的记录版本进行比较。如果它们不匹配,则更改失败并向用户解释发生了什么。

您可以在多个位置执行第二步 - 在业务层,触发保存的事件处理程序或用于更新记录的存储过程中。

(如果您的数据模型在结构上与您向用户提供的数据模型不同,这会变得有点复杂,但这不是一个不可逾越的障碍。)

悲观锁定从未如此简单。引用another stack overflow question的优秀答案:

  

[悲观锁定]要求你   小心你的申请   设计以避免死锁。使用   悲观锁定你​​需要一个   直接连接到数据库(如   通常是两个案例   层客户端服务器应用程序)或   外部可用的交易ID   可以独立使用   连接。

您还需要为悲观锁实现超时机制,以便疏忽用户无法无限期地锁定记录。