READ COMMITTED
在(悲观类型,不是 RCSI)下运行时,我刚刚看到UPDATE
的 IX 锁死锁,其中SELECT
的共享锁位于PAGE
-level。SELECT
使用并行执行计划运行。两者都没有明确使用事务。我理解UPDATE
s 隐式创建事务。这是否表明并行SELECT
s 也会创建隐式事务?对于非并行SELECT
s 来说,情况不是这样吗?
我发现这相当令人困惑,因为教科书中的死锁例子都没有显示两个无事务查询死锁。
READ COMMITTED
在(悲观类型,不是 RCSI)下运行时,我刚刚看到UPDATE
的 IX 锁死锁,其中SELECT
的共享锁位于PAGE
-level。SELECT
使用并行执行计划运行。两者都没有明确使用事务。我理解UPDATE
s 隐式创建事务。这是否表明并行SELECT
s 也会创建隐式事务?对于非并行SELECT
s 来说,情况不是这样吗?
我发现这相当令人困惑,因为教科书中的死锁例子都没有显示两个无事务查询死锁。
这不是交易
如果您玩锁兼容性战舰™️,您会发现共享锁无法轻易击沉您的驱逐舰,但对象级共享锁是另一种鱼雷。您甚至没有时间只进行一次 ping。
在大多数情况下,S 锁的获取和释放都非常快,但有些事情会延长这些锁的使用时间。我曾在博客中讨论过与使用预取的键查找相关的问题:
我首先要查看的是并行选择查询的查询计划,看看是否有任何具有预取属性的查找。在某些情况下,使用额外的索引列修复查找很容易。在其他情况下,您可能需要提示不同的索引。
如果根据较差的基数估计或由于参数嗅探而选择查找,您可能会决定采用不同的路径来解决问题。
如果不是这种情况,请提供选择和修改查询的查询计划,以及任何有用的上下文信息,如表和索引定义、触发器、索引视图等。
是的,
SELECT
将在事务中运行(如果需要,请创建一个事务,因为您正在自动提交模式下运行,或者您正在运行隐式事务,并且这SELECT
不是此处提到的例外)。这同样适用于串行或并行执行计划。如果您在一个窗口中以自动提交模式从一个大表启动
SELECT
,然后转到另一个窗口并运行当原始程序
SELECT
仍在运行时,您应该看到持有的锁SELECT
被分配给一个事务,如果您重复实验并将其添加CURRENT_TRANSACTION_ID()
到SELECT
大表的列表中,您将看到返回的值与request_owner_id
查询返回的值相匹配sys.dm_tran_locks
。这些自动提交的
SELECT
交易似乎没有出现,sys.dm_tran_session_transactions
如下所示(其中dm_tran_current_transaction
高兴地报告了其他 DMV 中未显示的交易的详细信息)。据我所知,它们也不会触发任何与交易相关的扩展事件,因此它们看起来像是主题的一个非常轻量级的变体。