SQL Server进程死锁

来源:互联网 发布:淘宝会员改版 编辑:程序博客网 时间:2024/05/17 02:11

SQL Server遇到错误“事务(进程 ID 144)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务。”之前也遇到过,上次没解决,这次再看看。既然出现“死锁”现象,问题肯定出在更新记录表上,所以找到被锁定的表,问题将会解决。找到出问题的存储过程,发现存在以下update语句

update mytable set name='Daniel' where id in (select id from mytable where name like '%d%') ;

猜测,问题可能出在批量更新表上。关于锁定记录,网上有以下SQL代码,使用with(updlock)关键词演示记录被锁定时的情景。

--打开一个SQL查询窗口,执行以下SQL语句begin tran;select * from mytable with(updlock) where id= 1;update mytable set name = 'Kate'  where id=1;waitfor delay '00:00:30';commit tran;--再打开一个SQL查询窗口,执行以下SQL语句update mytable set name = 'Lucy' where id=1;--再打开一个SQL查询窗口,执行以下SQL语句update mytable set name = 'Fiona' where id=1;


执行结果是mytable中id等于1的记录的name字段值为'Finona',虽然过程中出现了等待,但最终还是成功执行了记录。当一条记录处于锁定状态时,其他更新SQL语句需要等待它解锁,然后方可执行,如果超时,等待执行的SQL将会报“死锁”错误,执行失败。

本例中,批量更新表mytable时遇到错误,猜测待更新的记录中存在已锁定记录,尝试使用with(nolock)关键词在筛选id时就剔除锁定状态的记录。

经测试,这样做确实不再出现“死锁”情况,但也可能存在“漏”更新的记录,这种“漏”掉的记录或许会影响数据,也可能不影响。此时,需要从业务上评估其影响性。

综上所述,解决类似问题有以下两个途径:

1、调整业务逻辑,确保sql执行顺序合理

2、使用with(nolock)关键词,不过可能存在“漏”更新的风险,想其他办法处理。







0 0
原创粉丝点击