方言/驱动程序 – 我执行的每个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((object[]) sql.Parts); object fromItem = parts.FirstOrDefault(p => p.ToString().ToLower().Trim().Equals("from")); int fromIndex = fromItem != null ? parts.IndexOf(fromItem) : -1; object whereItem = parts.FirstOrDefault(p => p.ToString().ToLower().Trim().Equals("where")); int whereIndex = whereItem != null ? parts.IndexOf(whereItem) : parts.Count; if (fromIndex == -1) return sql; parts.Insert(parts.IndexOf(fromItem) + 2, " with(nolock) "); for (int i = fromIndex; i < whereIndex; i++) { if (parts[i - 1].Equals(",")) { parts.Insert(i + 2, " with(nolock) "); i += 2; } if (parts[i].ToString().Trim().EndsWith(" on")) { parts[i] = parts[i].ToString().Replace(" on", " with(nolock) on "); } } sql = new SqlString(parts.ToArray()); } return sql; } } 

此代码中有两个错误:

  1. 对于具有参数的SQL脚本此代码不起作用。
  2. 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; } }