sql >> Databasteknik >  >> RDS >> Sqlserver

Användning av TransactionScope med read uncommitted - är med (nolock) i SQL nödvändigt?

Kort svar:Nej

Långt svar:

Bara att definiera TransactionScope definierar inte att någon läsning eller skrivning kommer att anropas inom en transaktion.

För att köra något inom en transaktion måste du fortfarande öppna och utföra en transaktion!

TransactionOptions i TransactionScope för Timeout och IsolationLevel definiera bara standardinställningarna för alla transaktioner som skapats inom räckvidden utan att dessa alternativ uttryckligen anges. Egentligen skapar TransactionScope en Transaktion men den kommer inte att vara aktiv utan att öppna en ny Transaktion. Internt kommer detta att göra en del komplexa saker, kloning av transaktionen etc... så låt oss ignorera detta...

Utan en transaktion kan du inte definiera isoleringsnivån, valfri select-sats kommer att köras med IsolationLevel.ReadCommitted eftersom detta är standard för SQL Server.

Du kan också fråga session.Transaction.IsActive för att se om en transaktion för närvarande är aktiv för sessionen!

Låt oss ta en titt på följande kod, jag lägger några kommentarer för att göra det lite tydligare

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

Du kan också se hur SQL Server reagerar på dessa inställningar genom att använda SQL Server Profiler.

Skapa bara en ny Trace och se upp för Audit Login händelse, kommer texten för händelsen att inkludera isoleringsnivån och du kan se att den faktiskt gör en Audit Login varje gång en transaktion skapas, till exempel

 set transaction isolation level read uncommitted

--

Snälla rätta mig om någon av denna information kan vara felaktig, jag har precis kommit på det själv så det kan finnas risk för misslyckande;)



  1. Undantag 0x80040154 genereras under exekvering av ett enkelt ssis-paket i MS SQL 2008R2-miljö

  2. Infoga välj MySQL med förberedda uttalanden

  3. Jag vill infoga data i mysql-databasen med PDO av PHP. Men uppgifterna infogas inte

  4. java.lang.ClassCastException:oracle.sql.BLOB kan inte castas till oracle.sql.BLOB