锁 大家好,我正在研究锁并试图理解它们。
我的目标也是,能够在更新时锁定一行,但仍然允许用户能够从表中读取。 在我的阅读中,我读到了这个
"共享锁(S) 对于在悲观并发模型下读取的数据,保留共享锁。在保持共享锁的同时,其他事务可以读取但不能修改锁定的数据。 "
所以我在一次交易中有这个。
BEGIN TRAN
USE AdventureWorks2008R2
UPDATE Person.Address
SET AddressLine2 = 'Test Address 2'
WHERE AddressId = 5
现在在下一个交易中,我有同样的事情
BEGIN TRAN
USE AdventureWorks2008R2
UPDATE Person.Address
SET AddressLine2 = 'gar'
WHERE AddressId = 5
--ROLLback
我没有按照我的预期执行,但在另一项交易中
select * from AdventureWorks2008R2.Person.Address
这最后的转换并没有运行,我不确定为什么。既然它说我可以读取数据
我还看了它似乎工作的更新锁,因为我不能更新行,除非我comit或回滚转换。但是,我无法选择交易。我唯一可用的选项是使用独占锁并读取未提交的? 只是寻找锁定正在更新的行的最佳方法,但同时允许读取该行和表。 谢谢。
答案 0 :(得分:1)
取决于资源锁定的取消模式。
这里有三种相关的锁定模式。共享(S),更新(U)和独占(X)。
锁兼容性矩阵如下
+---+----+----+---+
| | S | U | X |
+---+----+----+---+
| S | ✓ | ✓ | ✘ |
| U | ✓ | ✘ | ✘ |
| X | ✘ | ✘ | ✘ |
+---+----+----+---+
即。共享与其他共享或更新兼容。更新锁与共享锁兼容,但不与其他更新锁兼容,并且独占锁与任何东西都不兼容。
第一个事务获取U锁,然后将其转换为X锁以实际执行更新。第二个事务被阻止,因为S锁与X锁不兼容。
允许在更新行时读取行的唯一方法是使用read uncommitted
或其中一个快照隔离级别。后者将返回"之前"行的值。前者可以回归"脏"数据。即"之后"价值,但在承诺之前。