如何解决 sql 中的 lck_m_x Lock
Posted
技术标签:
【中文标题】如何解决 sql 中的 lck_m_x Lock【英文标题】:How to solve lck_m_x Lock in sql 【发布时间】:2012-04-03 10:00:50 【问题描述】:我有一个复杂的查询(没有任何锁定提示),它从许多表中获取数据,比如 Table1、Table2、Table3
下面是检索数据的代码(没有交易)
IDbCommand sqlCmd = dbHelper.CreateCommand(Helper.MyConnString, sbSQL.ToString(), CommandType.Text, arParms);
sqlCmd.CommandTimeout = 300;
ds = dbHelper.ExecuteDataset(sqlCmd);
在应用程序中,此查询每 2 分钟运行一次
当我触发一个简单的更新查询时说
Update Table1 set Col1='abc' where ID=100
(其中 ID 是 int 和主键 + 聚集索引)
更新查询被延迟并且多次超时 下面是日志
我该如何解决这个问题。
【问题讨论】:
【参考方案1】:您可以在隔离级别为 SNAPSHOT 的事务中执行查询。这样,您的查询将不会获取任何(共享)锁,并且您的 UPDATE 不必等待排他锁(假设表上阻止您的 UPDATE 的锁的来源实际上是应用程序运行的查询每两分钟...)
作为参考,请查看 MSDN 上的 Working with Snapshot Isolation 和 SET TRANSACTION ISOLATION LEVEL。
因评论而编辑:
首先,为您的数据库启用 ALLOW_SNAPSHOT_ISOLATION:
ALTER DATABASE YourDB SET ALLOW_SNAPSHOT_ISOLATION ON
然后,将查询编写如下:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT Column1, Columns2, ...
FROM Table1
LEFT JOIN Table2
ON Table1.Columns45 = Table2.Column3
[... your complex query ...]
举个例子就够了吗?
【讨论】:
你能举个小例子吗?【参考方案2】:如果您不想在修改数据时等待读取查询,最好使用READ_COMMITTED_SNAPSHOT。
可以透明开启,不影响你的应用代码,没有副作用。
SNAPSHOT 有很多副作用,例如,虽然您没有锁定数据修改,但您在提交时可能会遇到数据冲突问题,这个问题非常难以处理。
【讨论】:
以上是关于如何解决 sql 中的 lck_m_x Lock的主要内容,如果未能解决你的问题,请参考以下文章