【问题标题】:How to check if a table is locked in sql server如何检查表是否在sql server中被锁定
【发布时间】:2009-10-02 20:36:23
【问题描述】:

我有一个在 sql server 上运行的大型报告。运行需要几分钟。我不希望用户单击两次运行。由于我将整个过程包装在事务中,如何检查表是否被事务锁定?如果是这样,我想返回一条错误消息,说“报告正在生成,请在几分钟后重试”。

如何做到这一点?

【问题讨论】:

    标签: sql sql-server concurrency locking


    【解决方案1】:

    您可以使用sys.dm_tran_locks 视图,该视图返回有关当前活动的锁管理器资源的信息。

    试试这个

     SELECT 
         SessionID = s.Session_id,
         resource_type,   
         DatabaseName = DB_NAME(resource_database_id),
         request_mode,
         request_type,
         login_time,
         host_name,
         program_name,
         client_interface_name,
         login_name,
         nt_domain,
         nt_user_name,
         s.status,
         last_request_start_time,
         last_request_end_time,
         s.logical_reads,
         s.reads,
         request_status,
         request_owner_type,
         objectid,
         dbid,
         a.number,
         a.encrypted ,
         a.blocking_session_id,
         a.text       
     FROM   
         sys.dm_tran_locks l
         JOIN sys.dm_exec_sessions s ON l.request_session_id = s.session_id
         LEFT JOIN   
         (
             SELECT  *
             FROM    sys.dm_exec_requests r
             CROSS APPLY sys.dm_exec_sql_text(sql_handle)
         ) a ON s.session_id = a.session_id
     WHERE  
         s.session_id > 50
    

    【讨论】:

    • 很棒的查询。
    【解决方案2】:

    更好的是,考虑专为此设计的sp_getapplock。或者使用SET LOCK_TIMEOUT

    否则,您将不得不对 sys.dm_tran_locks 做一些事情,我只会将它用于 DBA 的东西:而不是用于用户定义的并发。

    【讨论】:

    • SET LOCK_TIMEOUT 是最好的解决方案
    【解决方案3】:

    如果您正在验证是否对表应用了锁,请尝试以下查询。

    SELECT resource_type, resource_associated_entity_id,
        request_status, request_mode,request_session_id,
        resource_description, o.object_id, o.name, o.type_desc 
    FROM sys.dm_tran_locks l, sys.objects o
    WHERE l.resource_associated_entity_id = o.object_id
        and resource_database_id = DB_ID()
    

    【讨论】:

    • 我不知道为什么,但其他答案都没有对我产生任何影响。就是这个答案……
    【解决方案4】:

    sys.dm_tran_locks包含会话的锁定信息

    如果你想知道某个特定的表是否被锁定,你可以使用下面的查询

    SELECT 
     * 
    from 
     sys.dm_tran_locks 
    where 
      resource_associated_entity_id = object_id('schemaname.tablename')
    

    如果您有兴趣查找用户的登录名和正在运行的查询

    SELECT
     DB_NAME(resource_database_id)
     , s.original_login_name
     , s.status
     , s.program_name
     , s.host_name
     , (select text from sys.dm_exec_sql_text(exrequests.sql_handle))
     ,*
    from
      sys.dm_tran_locks dbl
         JOIN sys.dm_exec_sessions s ON dbl.request_session_id = s.session_id
      INNER JOIN  sys.dm_exec_requests exrequests on dbl.request_session_id = exrequests.session_id
    where
     DB_NAME(dbl.resource_database_id) = 'dbname'
    

    欲了解更多信息locking query

    更多关于sys.dm_tran_locks 的信息

    【讨论】:

      【解决方案5】:
      SELECT 
      db_name(rsc_dbid) AS 'DATABASE_NAME',
      case rsc_type when 1 then 'null'
                    when 2 then 'DATABASE' 
                    WHEN 3 THEN 'FILE'
                    WHEN 4 THEN 'INDEX'
                    WHEN 5 THEN 'TABLE'
                    WHEN 6 THEN 'PAGE'
                    WHEN 7 THEN 'KEY'
                    WHEN 8 THEN 'EXTEND'
                    WHEN 9 THEN 'RID ( ROW ID)'
                    WHEN 10 THEN 'APPLICATION' end  AS 'REQUEST_TYPE',
      
      CASE req_ownertype WHEN 1 THEN 'TRANSACTION'
                         WHEN 2 THEN 'CURSOR'
                         WHEN 3 THEN 'SESSION'
                         WHEN 4 THEN 'ExSESSION' END AS 'REQUEST_OWNERTYPE',
      
      OBJECT_NAME(rsc_objid ,rsc_dbid) AS 'OBJECT_NAME', 
      PROCESS.HOSTNAME , 
      PROCESS.program_name , 
      PROCESS.nt_domain , 
      PROCESS.nt_username , 
      PROCESS.program_name ,
      SQLTEXT.text 
      FROM sys.syslockinfo LOCK JOIN 
           sys.sysprocesses PROCESS
        ON LOCK.req_spid = PROCESS.spid
      CROSS APPLY sys.dm_exec_sql_text(PROCESS.SQL_HANDLE) SQLTEXT
      

      【讨论】:

        【解决方案6】:

        检查表是否被锁定的最简单方法是更新该表中的字段。如果表被锁定,您将收到类似以下的错误消息:

        错误 1099 (HY000): 表 'accounts' 被 READ 锁锁定,无法更新 MariaDB [测试]>

        因此,只需为您要检查的表创建一个“UPDATE 查询(或执行操作的另一个查询),看看您是否收到上述错误消息。

        你有没有忘记锁上你家的门?检查门是否被锁定的唯一方法是手动检查门是否打开。这是我能描述它的最佳方式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-29
          • 2010-09-13
          相关资源
          最近更新 更多