Dialetto / Driver – Ogni SELECT che eseguo, aggiungi con (nolock)

Ho bisogno di conoscere un modo per implementare nel mio sistema, un driver o dialetto che, ogni volta che eseguo una SELECT in Nhibernate, la SELECT aggiunge con (nolock) con essa. Ho bisogno che sia in C # e in NHibernate, non direttamente nel DB!

Spero tu possa capire !

Grazie !

È ansible modificare sql utilizzando un Interceptor e sovrascrivendo il metodo OnPrepareStatement , qualcosa del genere:

 public class AddNoLockHintsInterceptor : EmptyInterceptor { public override SqlString OnPrepareStatement(SqlString sql) { // Modify the sql to add hints return sql; } } 

E qui c’è un modo per registrare l’intercettore con NHibernate:

 var session = SessionFactory.OpenSession(new AddNoLockHintsInterceptor()); 

L’uso WITH(NOLOCK ) è la stessa cosa dell’utilizzo di un livello di isolamento della transazione READ UNCOMMITED come discusso qui: Quando si dovrebbe usare “with (nolock)” .

È ansible specificare il livello di isolamento della transazione quando si iniziano nuove transazioni con NHibernate:

 var session = SessionFactory.OpenSession(); session.BeginTransaction(IsolationLevel.ReadUncommitted); 

Non lo consiglierei a meno che tu non sappia davvero cosa stai facendo. Ecco alcune ulteriori informazioni sull’argomento: Perché utilizzare un livello di isolamento READ UNCOMMITTED? .

Spero che questo possa aiutare qualcuno, ho usato questo codice per aggiungere suggerimenti di blocco alla maggior parte delle domande, relative alla risposta 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; } } 

Ci sono due errori in questo codice:

  1. Per lo script SQL con parametro Questo codice non funzionerà.
  2. SqlString.Parts non è compilato, sto usando NHibernate 4.0.0.4000

Ecco la correzione:


 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; } }