当前位置: 代码迷 >> Sql Server >> update 触发器 死锁有关问题
  详细解决方案

update 触发器 死锁有关问题

热度:92   发布时间:2016-04-24 09:22:56.0
update 触发器 死锁问题
小弟近日被老大要求给某张表添加一个update 触发器,添加完成之后大部分情况下是OK的,但是某一个操作总是发生死锁。

目前不清楚这个操作具体情况,但根据业务逻辑大概是这样的:
{
开启事务
...
update TASK_TBL xx
...
(可能还会对TASK_TBL这个表进行update操作)
..
结束事务
}

小弟写的触发器:
CREATE TRIGGER PDOCV_PICKUP_TRG ON avaegp.TASK_TBL
AFTER UPDATE 
AS
IF UPDATE(INBOX_USER_ID)
BEGIN 
DECLARE @ID VARCHAR(18),@USERID VARCHAR(64);
SELECT @ID=REF_NO FROM INSERTED;
SELECT @USERID=INBOX_USER_ID FROM INSERTED;
IF @USERID IS NOT NULL
UPDATE avapems.APPLICATION_SUB SET HAS_PICKUP = 'Y' WHERE APPLICATION_NO = @ID;
ELSE
UPDATE avapems.APPLICATION_SUB SET HAS_PICKUP = 'N' WHERE APPLICATION_NO = @ID;
END

即在update TASK_TBL之后对APPLICATION_SUB 表进行update

敬请各位大侠伸出援手!
------解决思路----------------------
设计应考虑:
1、此触发器能不能保证每个INBOX_USER_ID有一个REF_NO;
2、每次更新的INBOX_USER_ID是否相同;

此触发器只能应用更新1条的情况。
若是更新多行,@ID只是最后一条记录的ID。
应考虑更新行数为0,1,n的情况,0行则直接返回,n行则采取游标等方式处理。

------解决思路----------------------
你业务中对TASK_TBL的批量更新,要改成游标、都按照REF_NO升序的次序逐个处理
这样不会因为A会话处理REF_NO的次序是(1,2),B会话处理REF_NO的次序是(2,1),它们各种通过触发器更新了APPLICATION_SUB记录后就死锁了。
如果都按照REF_NO升序的次序来处理,就只会发生等待或超时。
------解决思路----------------------
看代码没什么问题,死锁是由2个进程互锁资源造成的,只提供一个进程的代码无法分析.
建议启用1222跟踪标记,发生死锁时查看SQL日志,有详细的死锁日志以利分析.

dbcc traceon(1222,-1)
  相关解决方案