Transaction Isolation Level Scopes

12,512

Solution 1

Run the following and see for yourself:

CREATE PROCEDURE dbo.KeepsIsolation
AS
BEGIN
PRINT 'Inside sproc that does not change isolation level';
DBCC USEROPTIONS;
END
GO

CREATE PROCEDURE dbo.ChangesIsolation
AS
BEGIN
PRINT 'Inside sproc that changes isolation level';
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
DBCC USEROPTIONS;
END
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
DBCC USEROPTIONS;
EXEC dbo.KeepsIsolation;
DBCC USEROPTIONS;
EXEC dbo.ChangesIsolation;
-- demonstrates that isolation level restored to REPEATABLE READ after exiting the procedure
    DBCC USEROPTIONS;

Solution 2

From MSDN

If you issue SET TRANSACTION ISOLATION LEVEL in a stored procedure or trigger, when the object returns control the isolation level is reset to the level in effect when the object was invoked. For example, if you set REPEATABLE READ in a batch, and the batch then calls a stored procedure that sets the isolation level to SERIALIZABLE, the isolation level setting reverts to REPEATABLE READ when the stored procedure returns control to the batch.

Solution 3

DBCC USEROPTIONS will display the current isolation level, along with all of the other SET options.

Solution 4

From books on line

Only one of the TRANSACTION ISOLATION LEVEL options can be set at a time, and it remains set for that connection until it is explicitly changed. This becomes the default behavior unless an optimization option is specified at the table level in the FROM clause of the statement.

Solution 5

Isolation level does not roll back with the transaction.

Isolation level stays current even if you call into procedures and functions.

Share:
12,512
SurroundedByFish
Author by

SurroundedByFish

Born yesterday.

Updated on June 06, 2022

Comments

  • SurroundedByFish
    SurroundedByFish about 2 years

    What are the scoping rules for transaction isolation levels in SQL Server 2005? I know what the different levels mean, but not how to properly apply them outside of a manually run script. I can't find a guide for practical use in production-quality code.

    Obviously, the scope begins when you use a command like this:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
    

    But where does it end? If I set the iso level in a stored procedure and then that proc calls another, does the nested proc inherit it? Even better, if I escalate the iso level inside the nested proc is it going to carry back out into the calling proc? Do transaction commands like BEGIN TRAN, ROLLBACK, and COMMIT make any differences?

    When a stored proc is called by an application or an agent job do the isolation level changes persist in some way? Do I always have to revert to the default READ COMMITTED at the end of each proc?

    I would test it in different situations but I don't know how to read what the current isolation level is set to.

    • ChaseMedallion
      ChaseMedallion about 7 years
      The fact that the scope of this goes beyond the current transaction (and, due to connection pooling, beyond the current "session") can burn you. See this post I wrote on the subject.
  • SurroundedByFish
    SurroundedByFish about 15 years
    So it looks like the parent proc doesn't get affected by changes to the iso level within the child proc, but the child proc inherits the parent's iso level as the default.
  • redcalx
    redcalx over 14 years
    However, the accepted answer demonstrates that this is not true - changing the the ISOLATION level within a stored proc does not change the level for a calling stored proc. Either the docs are wrong or I've misunderstood.
  • rsutormin
    rsutormin over 13 years
    Agree with the previous comment. While I appreciate the quoting of the BOL comment, this seems to be at odds with the accepted answer.
  • TomTom
    TomTom about 10 years
    Actually it is correct. It also is NOT COMPLETE. Now, if you ignore the exception given in the documentation (check quote from Andrey) then - ah - yeah, this is the type of bad answer that one posts.