Viv*_*tra 8 sql-server concurrency isolation-level update
我有一个关于 SQL Server 的 UPDATE 语句的内部工作原理的问题。我试图了解如果同时收到或服务以下 2 个更新语句会发生什么:
| Session 1 - Statement 1 | Session 2 - Statement 2
| -------------------------+-------------------------
| update dbo.Table1 | update dbo.Table1
| set Value = 10 | set Value = 20
| where ID = 1 | where ID = 1
? and Value = 0; | and Value = 0;
(t)
Run Code Online (Sandbox Code Playgroud)
据我了解,更新将首先选择需要使用共享锁更新的行,这意味着两个更新语句都可以选择特定行。然后它请求一个排它锁来更新列值。因此,结果似乎将 Value 设置为 20。
我错过了什么还是我的理解正确?
连接的隔离级别设置为 READ UNCOMMITTED。
Pau*_*ite 13
我有一个关于 SQL Server 的 UPDATE 语句的内部工作原理的问题。
该语句描述了对数据库的所需逻辑更改。运行时物理上发生的事情取决于执行计划、数据库的状态以及其他并发运行的语句/查询正在做什么。
我提到这一点是因为您的问题与实现细节非常相关。
据我了解,更新将首先选择需要使用共享锁更新的行,这意味着两个更新语句都可以选择特定行。
这通常不会发生。
在大多数隔离级别(包括READ UNCOMMITTED
问题中指定的)下,SQL ServerU
在定位要更新的行时将采用更新 ( ) 锁。这是添加的一个实现细节,以提供一些针对常见形式的转换死锁的保护(这并不总是足够的,但它确实有帮助)。
注意:SQL Server 可以选择任何方便的访问方法来定位要更新的行。例如,它可能选择使用非聚集索引。更新仍将最终更新基表和任何适用的二级索引,但操作顺序可能不同。
这意味着U
锁不一定像人们预期的那样序列化。例如,问题中的一个更新语句可能选择通过二级索引定位记录,在这种情况下,该索引中的条目U
应用了锁。没有什么可以阻止第二个更新语句选择使用扫描基表(堆或集群)来定位记录的计划。
在这种情况下,第二次更新可以获得U
基表中行的锁,而第一次更新持有U
链接到相同基表行的二级索引中的行的锁。
在另一种情况下,SQL Server 可能能够选择单个运算符更新计划(例如,如果 上存在聚集索引(ID, Value)
)。在这种情况下,会X
立即对聚集索引进行排他锁 - 没有先前的U
锁。
然后它请求排他锁来更新列值。
数据更改操作总是X
在更改之前锁定。这个锁一直保持到事务结束。它可能涉及也可能不涉及将当前持有的U
锁转换为X
.
例如,如果要更新的行是使用基表定位的,U
则将X
在基表更新操作符中保存并转换为。如果该行是使用二级索引定位的,U
则保留在该索引上,并X
在基表上获取新锁。两者U
和X
都在不同的资源上同时举行。
因此,结果似乎将 Value 设置为 20。
根据时间和两个更新语句中的每一个选择的执行计划,有许多可能的结果。仅选择一些更有趣的:
场景一:
U
在读取时获取基表行上的锁。U
在基表的同一行上等待获取。U
锁并且发现无事可做,因为现在 Value != 0。结果:值设置为 10。
场景2:
U
在读取时获取基表行上的锁。U
在基表中的同一行上获取。U
锁并且发现无事可做,因为现在 Value != 0。结果:值设置为 20。
场景3:
U
二级索引的锁(定位要更新的行)。U
基表上的锁(定位要更新的行)。X
在基表行上获取以执行更新,但被会话 2 持有的锁阻塞U
。U
在基表上的锁定转换为X
并将 Value 设置为 20。X
在二级索引行上获取以更新它,但被会话 1 持有的锁阻塞U
。结果:不确定。值可能最终为 10 或 20。
这些只是一些可能性。试图预测详细的引擎锁定行为通常是错误的(在我看来)。而是专注于为要进行的更改编写正确的逻辑规范,并使用提供所需保证的隔离级别。
问题的编写方式让我觉得您可能真的在问“丢失的更新”。如果是这种情况,请在提出更具体的新问题之前,像以下一样查看现有的问答:
说到写作,没有“同一时间”这样的东西。一个会话将“赢得”锁的竞争,并首先更新值;“失败者”将更新下一个值,而下一个读者将反映其更改。
顺便说一句,隔离级别在这里没有任何影响(除非有包含其他语句的显式事务),并且无论如何READ UNCOMMITTED
对 DML 没有意义。为什么要在连接级别设置?你的恐怖故事还不够多吗?你需要更多吗?还有更多?
归档时间: |
|
查看次数: |
606 次 |
最近记录: |