因为我已经识别出同时查询的表的锁定,所以我决定启用对我来说不熟悉的ISOLATION LEVEL SNAPSHOT。
ALTER DATABASE RM2 SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
ALTER DATABASE RM2 SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE RM2 SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE RM2 SET MULTI_USER;
但现在我想知道是否可以自动对所有现有查询应用此隔离级别,因为此DB包含大量视图,存储过程,表值函数,并且被许多不同的应用程序查询(例如SSRS,SSAS, ASP.NET与ADO.NET,ADO连接从Excel)。
如果我理解正确,我必须修改查询以使用IsolationLevel.Snapshot,例如:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
GO
BEGIN TRAN SparePartReport
SELECT TOP 100 PERCENT * FROM DBO.Last3MonthSparepartReport
COMMIT TRAN SparePartReport
问:是否有可能以最小化努力,因为我无法更改所有应用程序和查询。另一个问题似乎是我无法直接在Views上应用IsoalationLevel。
注意:数据库中大多数相关的表都是一整天都是只读的,因为数据是通过Windows服务和存储过程一夜之间导入的。
提前致谢
虽然@Maximilian的答案似乎是正确的,但在同时运行大型报表时,我仍然在ASP.NET应用程序中遇到死锁/暂时的情况。 Here is the followup question
答案 0 :(得分:3)
您不必使用ISOLATION LEVEL SNAPSHOT来使用行版本而不是锁。你可以使用
ALTER DATABASE RM2 SET READ_COMMITTED_SNAPSHOT ON;
告诉您的数据库它应该使用ISOLATION LEVEL READ COMMITTED进行行版本控制。因为这是默认的隔离级别,所以当前没有指定不同隔离级别的查询将自动使用行版本。
供参考:MSDN
答案 1 :(得分:0)
如果数据库具有READ_COMMITTED_SNAPSHOT ON并且事务隔离级别为READ_COMMITTED(默认设置),则从数据库读取将自动使用快照隔离。
但是,除非事务隔离级别为SNAPSHOT,否则更新仍在语句的读取部分使用锁。您不能告诉数据库更改默认的事务隔离级别,因为它的作用域是连接而不是数据库。您需要基于每个连接const listSchema = mongoose.Schema({
user: { type: mongoose.Schema.Types.ObjectId, ref: "Users" },
name: { type: String, required: true },
description: {type:String, required: true},
image: {type:String},
symbol: {type: String, required: true}
});
或使用customizing transaction isolation level的其他方法之一。