开放式并发冲突检测的四种方法(希望补充)

         由于在 BugTiger 中需要用到冲突检测 , 所以对冲突检测进行了学习 , 现总结了如下四种方法 :

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

.使用时间戳.

       在数据库的表中添加一个时间戳列或版本列.时间戳列与对表内容的查询一起返回.当试图更新时,数据库中的时间戳值将与被修改行中的原始时间戳值进行比较.如果这两个值匹配,则执行更新,同时时间戳列被更新为当前时间以反映更新.如果这两个值不匹配,则发生开放式并发冲突.

 

示例

表结构(Method1):

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

Method1.JPG
BugTimeStamp
为时间戳列.

当用户取得数据时,BugTimeStamp列也返回给用户.

None.gif SELECT  BugID, BugType, BugTimeStamp
None.gif
None.gif
FROM  Method1
None.gif

当用户更新时

BugTimeStamp 作为条件进行比较 .
None.gif UPDATE  Method1
None.gif
SET  BugType  =   ' b '
None.gif
WHERE  (BugID  =   1 AND  (BugTimeStamp  =   0x00000000000004B1 )

更新时如果从上次读取数据到这次更新这段时间内已经被更改过了

, 条件显然是不成立了 . 因为每次更新记录时 ,timestamp 列中的值均会更新 .

 

.保留原始数据值的副本.

在查询数据库的数据时保留原始数据值的一个副本.在更新数据库时,检查数据库的当前值是否与原始值匹配.原始值保存在 DataSet ,当更新数据库时,数据适配器可以使用该原始值执行开放式并发检查.

 

示例 .

表结构(Method2)

Method2.JPG

 

None.gif UPDATE  Tasks 
None.gif
None.gif
SET  BugType  =  @ BugType 
None.gif
None.gif
WHERE  (BugID  =   @BugD AND  (BugType  =   @Original_BugType

 

@Original_BugType 可以这样指定
None.gif SqlUpdateCommand1.Parameters.Add( new  SqlParameter( " @Original_BugType " , SqlDbType.Char,  10 , ParameterDirection.Input,  false 0 0 "  BugType  " , DataRowVersion.Original,  null ));


.多列确定原则(我自己命名的,emembarrassed.gif)

       可以通过一表中的最后更新时间(LastUpdateDate)和最后更新用户(LastUpdateUserID)来确定一条记录是否已经被其他用户修改.如果只用最后更新时间,还是会有冲突发现,虽然这样的概率比较低,因为DateTime的精确度为百分之三秒,A用户取出后的足够短的时间内有B用户修改了数据,这时最后更新时间没有发生变化,但是数据有变化了,所以当A用户修改时实际上已经发生了冲突.使用最后更新用户(LastUpdateUserID),还是上述情况,由于LastUpdateUserID已经更改,只要A用户更新时同时检查最后更新时间(LastUpdateDate)和最后更新用户(LastUpdateUserID)就可以检查出冲突.

       在这种方法里假设了同一用户在百分之三秒不可能进行两次更新.我觉得这样的假设在通常情况下是合理的.

       示例:

       表结构(Method3)

Method3.JPG       取数据

   

None.gif      SELECT   [ BugID ] [ BugProject ] [ BugType ] [ LastUpdateDate ] [ LastUserID ]   FROM   [ Method3 ]
None.gif

       更新数据时

None.gif UPDATE   [ Method3 ]
None.gif
None.gif
SET  BugID  =   @BugID [ BugProject ]   =   @BugProject [ BugType ]   =   @BugType [ LastUpdateDate ]   =   @LastUpdateDate  ,  [ LastUserID ] =   @LastUserID ,
None.gif
None.gif
WHERE   [ BugID ] =   @BugID  ,  [ LastUpdateDate ] = @ OriginalLastUpdateDate ,  [ LastUserID ]   =   @OriginalLastUserID None.gif



.
BINARY_CHECKSUM

SQL联机丛书上的解释:

在表中任一行上计算的 BINARY_CHECKSUM(*) 返回相同的值,只要随后没有修改行.BINARY_CHECKSUM(*) 将为大多数(但不是全部)行更改返回不同的值,并可用于检测大多数行修改.

 

这各方法有很大的局限性 :

BINARY_CHECKSUM 在计算中忽略具有不可比数据类型的列.不可比数据类型是 textntextimagecursor 以及基本类型为前 4 个数据类型之一的 sql_variant.

字符串的区域设置可能导致具有不同表示法的字符串进行等值比较.在区分大小写的服务器中,字符串"McCavity""Mccavity" BINARY_CHECKSUM 值不同.反之,在不区分大小写的服务器中,上述字符串的 CHECKSUM 返回相同的校验值.

示例.

表结构(Method4)

Method3.JPG

取数据时把
BINARY_CHECKSUM(*)也返回给用户

None.gif SELECT   [ BugType ] , BINARY_CHECKSUM( * AS  RowCheckSum
None.gif
FROM   [ Method4 ]
None.gif


当用户修改数据时

None.gif UPDATE  Method4
None.gif
SET  BugType  =   ' b '
None.gif
WHERE  (BugID  =   1 AND  (CHECKSUM( * =  @ RowCheckSum) None.gif

 四种方式的比较

1.       优点:实现比较简单,timestamp 列中的值会更新.不足:要增加一个额外的字段.

2.       优点:可靠,不需要额外字段.不足:当字段较多时需要较多的参数.

3.       优点:2相比,传递的参数较少.不足:使用的字段对系统不一定有存在的意义,如例子中的最后更新时间(LastUpdateDate)和最后更新用户(LastUpdateUserID)有时对系统不是必需的.

4.       优点:不需要额外字段,只需要一个参数.不足:有些数据类型不可比BINARY_CHECKSUM, 字符串的区域设置可能导致具有不同表示法的字符串进行等值比较. 只为大多数(但不是全部)行更改返回不同的值. (笔者注:不知道这个大多数是什么概率.)

 

参考文档

n         《数据层组件设计与数据传递》http://www.yesky.com/20021112/1639500.shtml

n         hudan 的留言http://zitiger.cnblogs.com/archive/2005/08/05/208580.aspx#208605

n         TaskVision  http://www.windowsforms.net/Applications/application.aspx?PageID=20&tabindex=8

n         IssueVision  http://www.windowsforms.net/Applications/application.aspx?PageID=40&tabindex=8

n         SQL Server 联机丛书》

n         MSDN

 

转载于:https://www.cnblogs.com/zitiger/archive/2005/08/06/208881.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值