如何在sql中解决lck_m_x锁定问题

时间:2012-04-03 10:00:50

标签: sql sql-server-2008 tsql deadlock

我有一个复杂的查询(没有任何锁定提示),从许多表中获取数据,如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和主键+聚集索引)

更新查询会延迟,很多次都会超时 以下是日志 enter image description here

我该如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

您可以在隔离级别为SNAPSHOT的事务中执行查询。这样,您的查询将不会获取任何(共享)锁,并且您的UPDATE不必等待独占锁(假设阻止您的UPDATE的表上的锁源实际上是您的应用程序运行的查询每两分钟......)

如需参考,请查看MSDN上的Working with Snapshot IsolationSET 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 ...]

这样就足够了吗?

答案 1 :(得分:1)

如果您不想在修改数据时等待阅读查询,最好使用READ_COMMITTED_SNAPSHOT

它可以透明地打开,不会影响您的应用程序代码,也没有副作用。

SNAPSHOT有很多副作用,例如,当你没有锁定数据修改时,你可能会在提交时遇到冲突的数据问题,这个问题很难处理。