SQL Server搞出的写死锁:解决之道?(sqlserver写死锁)

SQL Server 是一种关系型数据库管理系统,处理记录的规则是每个记录在一个会话内只能被一个用户处理,如果另一个用户也想处理同一记录,应等待之前的操作 结束才能进行。但有时会发生“写死锁”,即一个事务锁定了一个记录,并且保持该记录处于锁定状态,而其它用户无法处理这条记录。这种情况将封锁数据库,影响其它应用程序的运行,因此有必要及时处理写死锁问题。

首先,检测是否有写死锁发生。可以在“管理 > 监视器 > 死锁”中查看当前存在的死锁情况;另外,也可以采用 SQL 语句“ SELECT * FROM sys.dm_tran_locks ”查询当前死锁情况,以便找出发生死锁的操作与用户。

其次,找出死锁发生的原因,一般有三种可能性:

(1)应用程序或查询对对象请求高级锁,且超时期限较长;

(2)存在循环引用关系,即事务A获取B对象,同时事务B获取A对象;

(3)死锁代码缺乏有效的释放步骤,出现无法释放死锁的情况。

最后,针对不同的写死锁情况采取相应的解决措施:

(1)应该在获取锁之前设置一个较短的超时期限;

(2)应尽量避免形成循环引用,比如采用先deny再request的模式;

(3)正确按照步骤释放锁,比如采用“try/catch/finally”结构,在finally中确保释放锁。

例如:

BEGIN TRANSACTION

UPDATE Table1

SET Col1 = ‘X’

WHERE Col2 = ‘Y’

WAITFOR DELAY ’00:00:10’表示等待10秒

UPDATE Table2

SET Col1 = ‘X’

WHERE Col2 = ‘Y’

COMMIT TRANSACTION

可修改为:

BEGIN TRANSACTION

BEGIN TRY

UPDATE Table1

SET Col1 = ‘X’

WHERE Col2 = ‘Y’

WAITFOR DELAY ’00:00:05′

UPDATE Table2

SET Col1 = ‘X’

WHERE Col2 = ‘Y’

END TRY

BEGIN CATCH

ROLLBACK TRANSACTION //确保释放锁

END CATCH

COMMIT TRANSACTION

总的来说,可以采取以上方法检测及解决 SQL Server 写死锁问题,有效避免写死锁影响程序正常运行。


数据运维技术 » SQL Server搞出的写死锁:解决之道?(sqlserver写死锁)