浅谈Sql 死锁(Dead Lock)
死锁是指进程之间相互block的,并形成一个block环路导致无unblock的情况。死锁必须发生在两个或更多的进程之间,如果是两个进程的话,那就是进程A block了进程B,而进程B也block了进程A.如果是三个进程之间发生死锁的例子有:进程A block了进程B,进程B block了进程C,进程C block 了进程A. Sql Sever在死的情况下会尝试终止某个进程,当然如果系统不中止某个进程或尝试中止失败,这个死锁的进程将一直保持死锁,除非人工干预来结束某个进程。
如果没有指定的话系统默认中止最后一个进程,因为这样是最优的对于要roll back这个事务的操作来说。然而从Sql server 2005起,可以通过设置每个session 的DEADLOCK_PRIORITY(-10~10),2008 可以支持这21个值,但Sql 2005只支持LOW 和NORMAL。系统将选取优先级别最低的进程进行终止。
下面通过一例子来理解下死锁:
A. 打开一个Sql 窗口(窗口1),并执行下列Sql语句
BEGIN TRAN;
UPDATE dbo.Products
SET unitprice = unitprice + 1.00
WHERE productid = 2;
B. 打开一个Sql 窗口(窗口 2),并执行下列Sql语句
BEGIN TRAN;
UPDATE [dbo].[Order Details]
SET unitprice = unitprice + 1.00
WHERE productid = 2;
C. 回到窗口1中执行
SELECT orderid, productid, unitprice
FROM [dbo].[Order Details]
WHERE productid = 2;
COMMIT TRAN;
发现窗口1被窗口2 block
D. 回到窗口2中执行
SELECT productid, unitprice
FROM dbo.Products
WHERE productid = 2;