A与B两个用户,都读取了数据库表tbl的同十条记录,在读取时,数据库对记录加共享锁,这时不会发生锁冲突,所以A与B都顺利的提取到了同样的数据,然后将数据各自存到DataSet的DataTable中,两人都读取完毕,数据库对记录解锁。
    接着A修改了其中几条记录,并且提交更改,提交时,数据库加更新锁至排它锁,更新完毕,数据库撤锁。
    接着B也修改了其中的记录,其中有几条记录是A所修改过的,但B并不知情。在提交更改时,由于记录原值与数据库中的现有值(已被A更改)不同,修改被拒绝了。
    以上是可能经常发生的一种并发冲突情况。上列事件依靠拒绝用户的修改来保持数据的一致性。然而考虑到用户体验,这会让用户非常冒火。B用户如果更改了全部十条或者是更多的记录后,在提交更改时,程序才来告诉他,他的所有更改因为另一用户的捷足先登而作废,对于B用户来说,是非常不公平的。B用户会抱怨,如果当初就知道自己的修改有可能不通过,那就应当在最初就告诉自己,以让自己不会白费这么多功夫。
    要避免这种情况,最好的办法是在提取记录的时候就给记录加上更新锁。这样,第二个提取数据的用户将得到警告。
    以上的处理方法是悲观锁定的方法,而DataSet则被设计为执行乐观锁定。
    [ 问题 ]
    1、如果使用的是强类型DataSet,如何在提取记录Fill到Table时对记录加上更新锁,强类型DataSet 自己生成了Fill方法,可它却是乐观的未加锁。自定义一个Fill方法吗?
    2、提取记录后,DataSet断开了与数据库的连接,数据库中对记录加的锁还在吗?如果用户提取了记录后,突然出去了一个星期,记录会一直这样锁下去吗?
    3、有更好的解决办法吗?

解决方案 »

  1.   

    1、如果使用的是强类型DataSet,如何在提取记录Fill到Table时对记录加上更新锁,强类型DataSet 自己生成了Fill方法,可它却是乐观的未加锁。自定义一个Fill方法吗? 
    你在DataSet中加锁是没有用的, 应为两个用户用的是不同的DataSet2.提取记录后,DataSet断开了与数据库的连接,数据库中对记录加的锁还在吗?如果用户提取了记录后,突然出去了一个星期,记录会一直这样锁下去吗?
    DataSet断开了与数据库的连接,锁自动回取消的, 普通的锁的生命周期在一个查询之内3. 没有太好的办法,只有给与友好的提示
      

  2.   

    感谢jzywh.
    1、我是说对数据库中的记录加锁,不是对Dataset。
    2、这样说来,要持有一个锁,Dataset是不能胜任的啦。
    3、靠乐观锁定来完成控制,真得不好处理呀
      

  3.   

    在msdn 搜索 处理并发异常,里面可以自己处理并发
    处理用户的响应
    您还需要用代码来处理用户对消息框的响应。可用选项为是否用建议的更改来改写数据库中的当前记录。如果用户选择是,则将在 preserveChanges 参数设置为 true 的情况下调用 DsAuthors1 的 Merge 方法。此时会采用 DsAuthors2 中数据行的初始版本,并将其与 DsAuthors1 中数据行的当前版本合并。由于记录的初始版本现在与数据库匹配,所以更新尝试将会成功。
      

  4.   

    我現在工作的這里有個作法:
    比如A用戶要操作一些數據,則把這些要操作的記錄先鎖住,這個鎖住不是數據庫的鎖,
    比如A用戶要操作A表的數據1(主ID)
    那麼我建一個table Lock專門存這個鎖的信息,結構如下:
    lockID,    lockrecordID, tableID,     lockedBy,       lockeddt,       lockTime
    1          1,         1(A表ID)        1(A用戶ID)      鎖定時間,       10(鎖定10分鍾沒操作無效)    
    如果B用戶要操作數據1則要到table Lock中去查看有人被人鎖,如果有人鎖了,並且在有效
    時間內(沒10分鍾),則提示A鎖了記錄,請稍後操作,
    如果沒人鎖,則要將A表的時間戳(每次用戶讀出數據都要帶出來保存起來)進行比較,如果不同,則提示該數據已經過時,需要刷新,
    如果A用戶操作完成,則解鎖,刪除這條記錄.
    另外有一問題是這記錄可能會因為沒人操作而增多,可以設JOb定時刪除說得不太好,不知對你有沒用