Ngo*_*vin 3 sql-server rollback locking
正如标题所说,在回滚事务时,我是否对整个数据库具有读/写访问权限?
或者仅对事务未写入的表进行读/写访问?什么是锁定行为?
如果我有读访问权限,当我读取事务回滚写入的表时会发生什么(查询失败还是等待)?
抱歉,我曾尝试在线阅读(ROLLBACK TRANSACTION (Transact-SQL)),但似乎没有触及这种深度。
答案在很大程度上取决于您的隔离级别、被回滚的事务持有什么类型的锁,以及您的非回滚会话试图做什么。
步骤 1)什么是锁定的?
在ROLLBACK
发出之前,该事务已经完成工作并获得了锁。您可以通过查看这些锁的详细信息sys.dm_tran_locks
:
SELECT tl.resource_type, tl.resource_associated_entity_id,
tl.request_status, tl.request_mode, tl.request_session_id,
tl.resource_description
FROM sys.dm_tran_locks tl
WHERE tl.request_session_id = <ROLLBACK session id>;
Run Code Online (Sandbox Code Playgroud)
在resource_type
和resource_associated_entity_id
会告诉你什么是锁定的。如果resource_type
是“对象”,则resource_associated_entity_id
是object_id
. 如果resource_type
是“Key”或“Page”,则resource_associated_entity_id
是hobt_id
. 有更多类型需要解码,但这两种类型涵盖了大多数场景。
SELECT tl.resource_type, tl.resource_associated_entity_id,tl.resource_database_id,
CASE WHEN resource_type = 'OBJECT'
THEN object_name(tl.resource_associated_entity_id,tl.resource_database_id)
WHEN resource_type IN ('KEY','PAGE')
THEN object_name(p.object_id)
END AS resource_name,
tl.request_status, tl.request_mode, tl.request_session_id,
tl.resource_description
FROM sys.dm_tran_locks tl
LEFT JOIN sys.partitions p ON p.hobt_id = tl.resource_associated_entity_id
AND tl.resource_database_id = db_id()
WHERE tl.request_session_id = <ROLLBACK session id>;
Run Code Online (Sandbox Code Playgroud)
最后,锁定模式提供有关如何使用该锁定的信息。BOL列出了所有不同的锁定模式。
第 2 步:什么会被阻止?
如果被回滚的事务没有锁定对象,则ROLLBACK
不会阻塞其他会话。那部分很容易。
这些锁是否会导致阻塞将取决于您的隔离级别以及您尝试执行的操作。Paul White有一个关于隔离级别的非常深入的系列,您可以阅读其中的许多详细信息。
读取、写入和隔离级别的不同组合将产生不同的阻塞结果。一般来说,写总是阻塞写。但是,写入可能会也可能不会阻止读取。在 SQL Server 的默认READ_COMMITTED
隔离级别下,写入将阻止读取。如果您正在使用READ_COMMITTED_SNAPSHOT
(又名“RCSI”又名“使用行版本控制的读取提交”),则写入不会阻止读取。
在所有情况下,如果另一个会话被 中的会话阻塞ROLLBACK
,等待的会话将等待直到ROLLBACK
释放锁。