Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Korzystanie z TransactionScope z niezatwierdzonym odczytem - czy z (nolock) w SQL jest konieczne?

Krótka odpowiedź:Nie

Długa odpowiedź:

Samo zdefiniowanie TransactionScope nie określa, że ​​jakikolwiek odczyt lub zapis zostanie wywołany w ramach transakcji.

Aby uruchomić coś w ramach transakcji, nadal musisz otworzyć i zatwierdzić transakcję!

TransactionOptions TransactionScope dla Timeout i IsolationLevel po prostu zdefiniuj domyślne dla każdej transakcji utworzonej w zakresie bez jawnie ustawionych tych opcji. W rzeczywistości TransactionScope tworzy Transakcję, ale nie będzie ona aktywna bez otwarcia nowej Transakcji. Wewnętrznie to zrobi kilka skomplikowanych rzeczy, klonowanie transakcji itp., więc zignorujmy to...

Bez transakcji nie można zdefiniować poziomu izolacji, każda instrukcja select zostanie uruchomiona z IsolationLevel.ReadCommitted ponieważ jest to domyślne ustawienie serwera SQL.

Możesz także wysłać zapytanie session.Transaction.IsActive aby sprawdzić, czy transakcja jest aktualnie aktywna dla sesji!

Rzućmy okiem na poniższy kod, umieściłem kilka komentarzy, aby był trochę bardziej przejrzysty

using (var scope = new TransactionScope(TransactionScopeOption.Required,
                    new TransactionOptions()
                    {
                        IsolationLevel = IsolationLevel.ReadUncommitted
                    }))
{

    using (var session = sessionFactory.OpenSession())
    {
        // outside any transaction...
        var x = session.Transaction.IsActive; // false;

        // read will be done with SQL Server default (ReadCommited)
        var pp = session.Query<Page>().Where(p => p.Photos.Count() > 1).ToList();

        using (var transaction = session.BeginTransaction())
        {
            // will use ReadUncommitted according to the scope
            var y = session.Transaction.IsActive; // true;

            var p1 = session.Get<Page>(1);

            transaction.Commit();
        }
        using (var transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
        {
            // will use ReadCommitted according to the transaction initialization
            var y = session.Transaction.IsActive; // true;

            var p1 = session.Get<Page>(1);

            transaction.Commit();
        }

        scope.Complete();
    }
}

Możesz również obserwować, jak SQL Server reaguje na te ustawienia, korzystając z programu SQL Server Profiler.

Po prostu utwórz nowy Trace i uważaj na Audit Login zdarzenie, tekst zdarzenia będzie zawierał poziom izolacji i widać, że faktycznie wykonuje Audit Login za każdym razem, gdy tworzona jest transakcja, na przykład

 set transaction isolation level read uncommitted

--

Proszę mnie poprawić, jeśli którakolwiek z tych informacji może być nieprawidłowa, sam to wymyśliłem, więc może istnieć pewien potencjał niepowodzenia;)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy można zmienić typ danych Data w Sql Server?

  2. Jak wykonać wyróżnianie trafień w wynikach zapytania pełnotekstowego programu SQL Server

  3. Tworzenie kolumny wyliczanej w SQL Server 2008

  4. Czy jest jakiś powód, aby na tej samej maszynie zainstalować SQL Server 2005 i 2008?

  5. sql server 2008:wybierz podciąg z pola