【问题标题】:How to know the lock status for a row, without updating the record如何在不更新记录的情况下知道一行的锁定状态
【发布时间】:2012-07-12 22:33:45
【问题描述】:

我正在使用 readcommited 隔离级别来更新一个事务中的一行。从其他事务中,我应该如何发现在同一行上放置了一个锁而不尝试更新该行。 有什么想法吗?

【问题讨论】:

标签: c# sql-server sql-server-2008 transactions locking


【解决方案1】:

检查锁的唯一方法是自己获取锁。这不是特定于数据库的,是并发的一般问题。任何形式的“检查”是否持有锁的 API 基本上都被破坏了,因为根据定义,基于此 API 检查结果执行的任何操作都是错误,就像基本过时、过时的信息一样.知道锁在 API 检查时未被持有并不意味着在 API 返回时未被持有。

如果你询问关于锁的问题,你不可能写出正确的程序。编写正确程序的唯一方法是获取锁。在 SQL 中和在任何其他编程语言中一样。

没有什么能阻止您尝试获取具有即时超时的锁 (SET LOCK_TIMEOUT 0) 并处理发生冲突时发生的锁超时错误。

【讨论】:

  • 感谢您提供设计信息。能否请您详细说明或解释一些获取锁的方法。
  • 使用lock hints。说明您的情况,也许我们可以提供更多详细信息。
  • 附带说明:使用 DMV 查询行锁基本上是不可能的,因为您必须确切地知道锁定协议和数据库的物理结构。恰当的例子:通过查找键锁定资源(祝你编译 that 好运)来检查键为 'foo' 的行是否被锁定是不够的。一个并发事务可能使用了页面粒度并且只锁定了包含该行的页面。你赢不了。
  • 我有一个查看屏幕和更新屏幕。更新屏幕中的第一个操作是选择操作,用于显示要编辑的数据,对于并发事务必须阻止该操作。但必须允许查看屏幕“选择”。
  • 无论如何,只要用户编辑屏幕,您就无法保持锁定。请改用optimistic concurrency。在最坏的情况下,使用明确的app locks。绝对不要对“编辑”屏幕使用数据锁。
【解决方案2】:

要获取关于锁的信息,可以执行sp_lock过程。

注意:需要VIEW SERVER STATE 权限。

在SQL Server 2008中,可以使用sys.dm_tran_locks动态管理视图。

【讨论】:

    【解决方案3】:

    我认为你可以在表级别而不是行级别找到锁

    试试下面的代码,它会给出当前锁定的表。

    SELECT t.name as [Table Name]
    FROM sys.dm_tran_locks as t1
    Join sys.objects o1 on o1.object_id = t1.resource_associated_entity_id
    Join sys.tables t on o1.object_id = t.object_id
    

    【讨论】:

    猜你喜欢
    • 2017-06-25
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2011-01-11
    • 2020-02-01
    • 2023-03-04
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多