无鱼之水

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

    使用RCSI可以使普通的数据库读取操作不再善用Share Lock,但不是所有的读操作都不会被阻塞。

    我一开始就把这个“读取操作”无限放大,认为从此不再有读/写操作相互阻塞的事情了。下面是不久之前系统里的一个例子,用来说明更新操作中,当SQL SERVER引擎用来确认更新范围的时候并不会读取快照,而是会使用和X锁不兼容的U锁。因此,即使一个语句的最终结果不会更新任何记录,他还是有可能会被阻塞。

/*SegmentA*/
BEGIN TRAN
UPDATE CL_CCMX
SET [JSDID] = 1
WHERE /*Confition1*/
ROLLBACK

 

    开两个会话分别执行SegmentA和SegmentB,会发现,SegmentB被阻塞。查看会话和锁情况:

 

    解决办法比较笨,将Where条件更换为使用临时表:

/*Solution*/
BEGIN TRAN
SELECT CCMXID
INTO #IDs
WHERE /*Confition*/
UPDATE CL_CCMX
SET [JSDID] = 1
WHERE CCMXID IN (SELECT ID FROM #IDs)
ROLLBACK
    因为我们没有想到更好的强迫SQLServer使用快照的方法。

    事情过去一段时间了。小记一把。

posted on 2010-12-30 19:41  陈伟强  阅读(291)  评论(0编辑  收藏  举报