假设我有三个存储过程:ProcA,ProcB和ProcC。它们都使用游标,具有分支(通过IF语句),并且都执行SELECT / UPDATE / INSERT语句。
此外,在它们引用的每个表上,它们都应用表提示“TABLOCKX”。此外,始终从事务中调用这些存储过程。
我担心的是,由于这些过程使用游标和分支,因此它们锁定表的顺序似乎很重要。例如,存储过程中使用表的顺序各不相同:
+--------+--------+--------------------+--------------------+
| ProcA | ProcB | ProcC (scenario 1) | ProcC (scenario 2) |
+--------+--------+--------------------+--------------------+
| TableA | TableA | TableB | TableD |
| TableB | TableC | TableC | TableA |
| TableD | TableE | TableD | TableC |
+--------+--------+--------------------+--------------------+
因此,如果ProcA和ProcC同时启动,SQL Server是否知道阻止ProcC直到ProcA完成,因为ProcC 可能需要TableA(取决于分支的条件)?< / p>
如果SQL Server允许两者同时运行,那么如果ProcC达到(方案2),它会不会死锁?由于ProcA被锁定了TableA并且ProcC被锁定到TableD,现在ProcA需要锁定TableD并且ProcC需要锁定TableA?
答案 0 :(得分:1)
您提出了两种情景;我将轮流回答。
首先,锁定是在引用它们引用的资源时获得的,而不是以先发制人的方式。所以,为了回答你的问题,对ProcC的调用不会锁定tableA,直到并且除非逻辑到达执行tableA的调用。
其次,您已经纠正了死锁的可能性。一般来说,如果您以相同的顺序锁定资源,则不会发生死锁。相反,如果您没有以相同的顺序锁定它们,那么您通过在代码中加入地雷来违反日内瓦公约。在这种情况下,如果你拿出红色鲱鱼,tableA和tableD在两个程序之间以相反的顺序被锁定。因此,如果他们同时执行,他们就有机会陷入僵局。