方言/驱动程序 – 我执行的每个SELECT,添加(nolock)
我需要知道一种在我的系统中实现的方法,一个驱动程序或方言,每当我在Nhibernate中执行SELECT时,SELECT都会添加with(nolock)。 我需要在C#和NHibernate中,而不是直接在DB中!
希望你能理解!
谢谢 !
可以使用Interceptor修改sql并覆盖OnPrepareStatement
方法,如下所示:
public class AddNoLockHintsInterceptor : EmptyInterceptor { public override SqlString OnPrepareStatement(SqlString sql) { // Modify the sql to add hints return sql; } }
这是一种用NHibernate注册拦截器的方法:
var session = SessionFactory.OpenSession(new AddNoLockHintsInterceptor());
使用WITH(NOLOCK
)提示与使用READ UNCOMMITED事务隔离级别相同,如下所述: 何时应使用“with(nolock)” 。
使用NHibernate启动新事务时,可以指定事务隔离级别:
var session = SessionFactory.OpenSession(); session.BeginTransaction(IsolationLevel.ReadUncommitted);
除非你真的知道你在做什么,否则我不会推荐这个。 以下是有关该主题的更多信息: 为什么使用READ UNCOMMITTED隔离级别? 。
希望这会对某人有所帮助,我使用此代码为大多数查询添加无锁提示,与答案dillenmeister相关
public class NoLockHintsInterceptor : EmptyInterceptor { public override SqlString OnPrepareStatement(SqlString sql) { // Modify the sql to add hints if (sql.StartsWithCaseInsensitive("select")) { var parts = new List
此代码中有两个错误:
- 对于具有参数的SQL脚本此代码不起作用。
- SqlString.Parts不是编译,我使用的是NHibernate 4.0.0.4000
这是修复:
public class NoLockInterceptor : EmptyInterceptor { public override SqlString OnPrepareStatement(SqlString sql) { //var log = new StringBuilder(); //log.Append(sql.ToString()); //log.AppendLine(); // Modify the sql to add hints if (sql.StartsWithCaseInsensitive("select")) { var parts = sql.ToString().Split().ToList(); var fromItem = parts.FirstOrDefault(p => p.Trim().Equals("from", StringComparison.OrdinalIgnoreCase)); int fromIndex = fromItem != null ? parts.IndexOf(fromItem) : -1; var whereItem = parts.FirstOrDefault(p => p.Trim().Equals("where", StringComparison.OrdinalIgnoreCase)); int whereIndex = whereItem != null ? parts.IndexOf(whereItem) : parts.Count; if (fromIndex == -1) return sql; parts.Insert(parts.IndexOf(fromItem) + 3, "WITH (NOLOCK)"); for (int i = fromIndex; i < whereIndex; i++) { if (parts[i - 1].Equals(",")) { parts.Insert(i + 3, "WITH (NOLOCK)"); i += 3; } if (parts[i].Trim().Equals("on", StringComparison.OrdinalIgnoreCase)) { parts[i] = "WITH (NOLOCK) on"; } } // MUST use SqlString.Parse() method instead of new SqlString() sql = SqlString.Parse(string.Join(" ", parts)); } //log.Append(sql); return sql; } }