sql >> Databáze >  >> RDS >> Sqlserver

Použití TransactionScope s nezávazným čtením - je s (nolock) v SQL nutné?

Krátká odpověď:Ne

Dlouhá odpověď:

Pouhá definice TransactionScope nedefinuje, že v rámci transakce bude vyvoláno jakékoli čtení nebo zápis.

Chcete-li provést něco v rámci transakce, stále musíte transakci otevřít a potvrdit!

TransactionOptions TransactionScope pro Timeout a IsolationLevel stačí definovat výchozí pro jakoukoli transakci vytvořenou v rámci oboru bez explicitně nastavených možností. TransactionScope ve skutečnosti vytvoří transakci, ale nebude aktivní bez otevření nové transakce. Interně to udělá nějaké složité věci, klonování transakce atd... takže to ignorujte...

Bez transakce nemůžete definovat úroveň izolace, jakýkoli příkaz select bude spuštěn s IsolationLevel.ReadCommitted protože toto je výchozí nastavení serveru SQL.

Můžete také zadat dotaz na session.Transaction.IsActive abyste zjistili, zda je transakce pro relaci aktuálně aktivní!

Pojďme se podívat na následující kód, přidal jsem několik komentářů, aby to bylo trochu jasnější

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

Můžete také sledovat, jak SQL Server reaguje na tato nastavení pomocí SQL Server Profiler.

Stačí vytvořit nový trasování a dávat pozor na Audit Login událost, text události bude obsahovat úroveň izolace a můžete vidět, že ve skutečnosti provádí Audit Login při každém vytvoření transakce, například

 set transaction isolation level read uncommitted

--

Prosím, opravte mě, pokud by některá z těchto informací mohla být chybná, právě jsem na to přišel sám, takže může existovat určitý potenciál selhání;)



  1. Jak opravit nesprávnou hodnotu řetězce v MySQL

  2. Geoprostorové mapování bodů ve Fluent NHibernate

  3. Jak získat řádky z tabulky, pokud je celkový počet řádků v Oracle více než 10?

  4. Živé migrace pomocí replikace MySQL