如何检查表是否在sql server中被锁定

时间:2009-10-02 20:36:23

标签: sql sql-server concurrency locking

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

如何实现这一目标?

6 个答案:

答案 0 :(得分:17)

您可以使用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

答案 1 :(得分:10)

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

否则,你必须对sys.dm_tran_locks做一些我只用于DBA的东西:不是用户定义的并发。

答案 2 :(得分:9)

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

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()

答案 3 :(得分:3)

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

如果您想知道某个特定表是否已锁定,您可以使用以下查询

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

@RequestMapping(value = "v3/", produces = { APPLICATION_JSON_VALUE })
public interface ParametersApi {

  @RequestMapping(
      value = "/parameters/currencies/{theCurrencyCode}",
      produces = { "application/json" },
      method = RequestMethod.GET)
  ResponseEntity<List<Currency>> GetCurrencies(@PathVariable String theCurrencyCode);

}

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

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

了解更多信息locking query

关于sys.dm_tran_locks

的更多信息

答案 4 :(得分:0)

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

<块引用>

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

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

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

答案 5 :(得分:0)

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