sql-server - SQL Server 中的只读锁

标签 sql-server sql-server-2008 locking

我似乎在 SQL Server 2008 中遗漏了一些有关锁的内容。这是我的情况:

  1. 开始翻译。
  2. 从表 A 中读取以确保找到特定行。
  3. 读取时,对读取的单行放​​置只读锁。如果没有找到,则抛出错误。
  4. 插入表 B,其中包含对表 A 的引用。
  5. 提交 tran(释放锁)。

由于各种设计限制,在这个特定实例中,我无法创建关系来为我管理此问题。所以我必须用代码来完成。

我不想对表 A 进行 XLOCK 或 UPDLOCK,因为我所在的事务只是从中读取,而不是写入。但是,显然我也不希望有任何其他内容来更新/删除引用的行。 所以我需要一个只读锁从外部角度

我不希望出现任何幻读。显然,我不希望出现不同的行版本。

一旦 tran 提交,就可以修改表 A,因为触发器(删除后)会将表 B 中的引用清空。

这就是我所拥有的:

BEGIN TRAN
-- test
IF NOT EXISTS (
  SELECT  1
  FROM    Table1
  WITH    (HOLDLOCK, ROWLOCK)
  WHERE   (ID = @ID)
  ) {throw}

  {perform insert into Table2}
COMMIT TRAN

最佳答案

将事务隔离级别设置为 REPEATABLE READ在您的交易期间。在我看来,这也比使用锁定提示更可取,因为代码实现更加清晰。

由于您只读取一行,因此无需担心范围插入到您的集合中,这是可重复读取的警告。

我建议阅读本书中的“锁定和闩锁”一章Professional SQL Server 2008 Internals and Troubleshooting 。它包含对 SQL Server 中可用的各种隔离级别的精彩解释(包括代码示例),以及描述每个数据异常场景(例如幻影等)的机制。

免责声明:我不在这本书的工资单上,但我有两本,一本是硬本,另一本是 Kindle 版,这就是我买了两次的好处!

关于sql-server - SQL Server 中的只读锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4427833/

相关文章:

sql-server - SQL Server : check whether a Trigger is Enabled or Disabled?

mysql - 如何将数据库的一列拆分为多列并将日期时间数据类型的值与字符串数据类型的值进行比较

sql-server - Visual Studio 2010 和 SQL Server

sql-server - 使用 XSLT 将分层 xml 转换为平面 xml

C# - 从字典中获取资源时锁定

mysql - MySQL InnoDB 是否使用 READ_COMMITTED 隔离级别锁定多行?

php - 无法将 Yii 与本地 SQL Server 2012 连接

sql - 使用两个数据库创建查询

Java 锁定 <这有什么问题?>

java - org.hibernate.ObjectNotFoundException : No row with the given identifier exists: Single table query