2016-09-18 72 views
0

假设我有三个存储过程:ProcA,ProcB和ProcC。它们都使用游标,具有分支(通过IF语句),并且全部执行SELECT/UPDATE/INSERT语句。TABLOCKX命令是否重要?

另外,在他们引用的每个表格上,他们都应用表格提示'TABLOCKX'。而且,这些存储过程总是从事务中调用。

虽然我的担心是,因为这些过程使用游标和分支,它们似乎锁定表的顺序可能很重要。例如,在表在存储过程中使用的顺序有所不同:

+--------+--------+--------------------+--------------------+ 
| ProcA | ProcB | ProcC (scenario 1) | ProcC (scenario 2) | 
+--------+--------+--------------------+--------------------+ 
| TableA | TableA | TableB    | TableD    | 
| TableB | TableC | TableC    | TableA    | 
| TableD | TableE | TableD    | TableC    | 
+--------+--------+--------------------+--------------------+ 

所以,如果PROCA和ProcC都开始在同一时间,将SQL服务器知道阻止ProcC直到PROCA完成,因为ProcC 可能需要TableA(取决于分支的条件)?

如果SQL Server允许同时运行,那么如果(方案2)到达ProcC,是不是会死锁?由于ProcA获得了TableA的锁定,并且ProcC被授予了TableD的锁定,现在ProcA需要在TableD上锁定,并且ProcC需要在TableA上锁定?

回答

1

您提出了两种情况;我会依次回答每个问题。

首先,锁定是在他们引用的资源被引用时获得的,而不是以先发制人的方式。因此,要回答您的问题,调用ProcC将不会锁定tableA,除非该逻辑达到执行对tableA的调用的点。

其次,你对死锁的可能性是正确的。一般来说,如果您以相同的顺序锁定资源,则不会发生死锁。相反,如果您的不是以相同的顺序锁定它们,则通过在代码中放置地雷来违反了“日内瓦公约”。在这种情况下,如果您取出红鲱鱼,tableA和tableD在两个过程之间以相反顺序锁定。所以,如果他们同时执行,他们有可能会陷入僵局。