TABLOCKX订单是否重要?

时间:2016-09-18 22:48:52

标签: sql sql-server sql-server-2012

假设我有三个存储过程: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?

1 个答案:

答案 0 :(得分:1)

您提出了两种情景;我将轮流回答。

首先,锁定是在引用它们引用的资源时获得的,而不是以先发制人的方式。所以,为了回答你的问题,对ProcC的调用不会锁定tableA,直到并且除非逻辑到达执行tableA的调用。

其次,您已经纠正了死锁的可能性。一般来说,如果您以相同的顺序锁定资源,则不会发生死锁。相反,如果您没有以相同的顺序锁定它们,那么您通过在代码中加入地雷来违反日内瓦公约。在这种情况下,如果你拿出红色鲱鱼,tableA和tableD在两个程序之间以相反的顺序被锁定。因此,如果他们同时执行,他们就有机会陷入僵局。