我有一个复杂的查询(没有任何锁定提示),从许多表中获取数据,如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和主键+聚集索引)
更新查询会延迟,很多次都会超时 以下是日志
我该如何解决这个问题。
答案 0 :(得分: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 ...]
这样就足够了吗?
答案 1 :(得分:1)
如果您不想在修改数据时等待阅读查询,最好使用READ_COMMITTED_SNAPSHOT。
它可以透明地打开,不会影响您的应用程序代码,也没有副作用。
SNAPSHOT有很多副作用,例如,当你没有锁定数据修改时,你可能会在提交时遇到冲突的数据问题,这个问题很难处理。