Mat*_*ias 3 sql-server transactions
在一个事务中,我正在创建一个引用另一个表的表.在第二个事务中,我对引用的表运行SELECT查询,但它被第一个事务阻止.这是为什么?
交易A:
BEGIN TRAN
CREATE TABLE Child (id int NOT NULL,
parentId int NOT NULL REFERENCES Parent (id));
Run Code Online (Sandbox Code Playgroud)
交易B:
BEGIN TRAN
SELECT * FROM Parent; -- This query is blocked
Run Code Online (Sandbox Code Playgroud)
查看活动监视器中的锁,我们可以看到第一个进程(创建表)在某个对象上保存了一个Sch-M锁(它只告诉我们对象id,如果我们查找它,我希望它是父对象表).同时,在尝试获取同一对象上的Sch-S锁时,第二个进程(从父表执行选择)被阻止.
查看MSDN文档,我们可以看到这些锁是Schema修改(Sch-M)和Schema稳定性(Sch-S) - 第二个查询需要模式稳定性锁,以确保obejct的模式在期间不会发生变化任何对对象进行模式更改的人都会执行查询和模式修改锁定.
为什么在父表上获得Sch-M锁?
因为修改父表中的行的任何人的执行计划已更改(特别是更改id或删除行) - 当从此表中删除行时,SQL Server现在需要确保子表中没有记录与您要删除的父ID相同的parentId.
即使select语句的执行计划不会改变,SQL Server也不需要锁定粒度来区分它可以安全运行的查询和不能查询的查询 - 在所有模式更改都不会发生之后非常频繁,因此没有必要在这种程度上优化这些类型的东西.
归档时间: |
|
查看次数: |
1647 次 |
最近记录: |