【问题标题】:Reading rows and table locked for updating读取行和表锁定以进行更新
【发布时间】:2014-11-08 03:30:06
【问题描述】:

锁 大家好,我正在研究锁并试图了解它们。

我的目标也是,能够在更新行时锁定行,但仍允许用户从表中读取。 在我的阅读中,我读到了这个

"共享锁 (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

最后一个交易没有运行,我不确定为什么。因为它说我可以读取数据

我还查看了它似乎工作的更新锁,因为除非我提交或回滚事务,否则我无法更新行。但是,我无法选择交易。我唯一可用的选择是使用排他锁并读取未提交吗? 只是寻找锁定正在更新的行的最佳方法,但同时允许读取该行和表。 谢谢你。

【问题讨论】:

  • 在您的事务中使用快照隔离级别。
  • 显示完整代码。您是否提交并结束交易。你知道单次更新就是交易吗?
  • @Blam 我没有结束交易,我正在开始交易并进入其他会话,并注意当我尝试访问和更新所述行时发生了什么。测试一下

标签: sql-server tsql


【解决方案1】:

这取决于资源上的锁被取出的模式。

这里有三种相关的锁定模式。共享 (S)、更新 (U) 和独占 (X)。

锁兼容矩阵如下

+---+----+----+---+
|   | S  | U  | X |
+---+----+----+---+
| S | ✓  | ✓ | ✘ |
| U | ✓  | ✘ | ✘ |
| X | ✘  | ✘ | ✘ |
+---+----+----+---+

即Shared 与其他 Shared 或更新兼容。更新锁与共享锁兼容,但其他更新锁不兼容,排他锁与任何东西都不兼容。

第一个事务在其上获得一个 U 锁,然后将其转换为 X 锁以实际执行更新。第二个事务被阻塞,因为 S 锁与 X 锁不兼容。

允许在更新时读取行的唯一方法是使用read uncommitted 或其中一个快照隔离级别。后者将返回该行的“之前”值。前者可能会返回“脏”数据。即“之后”值,但在提交之前。

【讨论】:

  • 起初以为那里还有另一个选择。只有两笔交易,所以更简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多