views:

314

answers:

1

I have a bunch of utility procedures that just check for some conditions in the database and return a flag result. These procedures are run with READ UNCOMMITTED isolation level, equivalent to WITH NOLOCK.

I also have more complex procedures that are run with SERIALIZABLE isolation level. They also happen to have these same kind of checks in them.

So I decided to call these check procedures from within those complex procedures instead of replicating the check code.

Basically it looks like this:

CREATE PROCEDURE [dbo].[CheckSomething]
AS
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

    BEGIN TRANSACTION

    -- Do checks

    COMMIT TRANSACTION

and

CREATE PROCEDURE [dbo].[DoSomethingImportant]
AS
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

    BEGIN TRANSACTION

    EXECUTE [dbo].[CheckSomething]

    -- Do some work

    COMMIT TRANSACTION

Would it be okay to do that? Will the temporarily activated lower isolation level somehow break the higher level protection or is everything perfect safe?

EDIT: The execution goes smoothly without any errors.

+1  A: 

It's all here for SQL Server 2005. A snippet:

When you change a transaction from one isolation level to another, resources that are read after the change are protected according to the rules of the new level. Resources that are read before the change continue to be protected according to the rules of the previous level. For example, if a transaction changed from READ COMMITTED to SERIALIZABLE, the shared locks acquired after the change are now held until the end of the transaction.

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.

In this example:

  • Each isolation level is applied for the scope of the stored proc
  • Resources locked by DoSomethingImportant stay under SERIALIZABLE
  • Resources used by CheckSomething are READ UNCOMMITTED
gbn
Thanks for the clarification, when I did this in the past I was outside of a stored proc so the behavior was different
Sam Saffron