Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unset/reset a transaction isolation level for SQL Server?

Maybe I'm misunderstanding something about transactions or what SQL Server is doing but consider the following T-SQL:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO

BEGIN TRANSACTION

-- DO SOME READS AND OTHER THINGS

COMMIT

-- OK, WHAT HAPPENS TO THE ISOLATION LEVEL AFTER THIS?

Maybe it doesn't matter, but I like the warm fuzzy feeling that I'm leaving things the way they were once I'm done doing what I'm doing. Is it possible to reset the isolation level back to the original state regardless of what the state was before?

like image 259
aarona Avatar asked Jan 07 '11 22:01

aarona


People also ask

How do I change the transaction isolation level in SQL Server?

The isolation level of the transactional support is default to READ UNCOMMITTED. You can change it to READ COMMITTED SNAPSHOT ISOLATION by turning ON the READ_COMMITTED_SNAPSHOT database option for a user database when connected to the master database.

How do I change the isolation level of a database?

How do I do this? From the tools menu select options. Under Query Execution/SQL Server/Advanced, change the value of SET TRANSACTION ISOLATION LEVEL to READ UNCOMMITTED.

Where is transaction isolation level set?

To set the transaction isolation level, use an ISOLATION LEVEL level clause. It is not permitted to specify multiple ISOLATION LEVEL clauses in the same SET TRANSACTION statement. The default isolation level is REPEATABLE READ . Other permitted values are READ COMMITTED , READ UNCOMMITTED , and SERIALIZABLE .

What is isolation level Autocommit?

There isn't a specific isolation level for autocommit transactions. They use whatever isolation level has last been declared for a connection (or the server default). Unfortunately, however, in the face of connection pooling1, what you think of as a "new" connection may in fact be a re-used one.


2 Answers

If your code is executed inside a stored procedure, the change only applies during the scope of the stored proc - when the stored proc returns, the isolation level for the connection will automatically revert to it's previous level:

create procedure dbo.IsoTest
as
    set transaction isolation level serializable
    begin transaction

    select transaction_isolation_level FROM sys.dm_exec_sessions where session_id = @@SPID

    select object_id from sys.objects

    commit
go
select transaction_isolation_level FROM sys.dm_exec_sessions where session_id = @@SPID
exec dbo.IsoTest
select transaction_isolation_level FROM sys.dm_exec_sessions where session_id = @@SPID

(Ignoring result set from sys.objects, this outputs 2, 4 and 2 as the isolation levels).

like image 73
Damien_The_Unbeliever Avatar answered Oct 20 '22 04:10

Damien_The_Unbeliever


You know the current level from sys.dm_exec_sessions.transaction_isolation_level

If you need to span batches, then use SET CONTEXT_INFO to preserve the value which can also be read from sys.dm_exec_sessions later on.

DECLARE @CurrentIsolationLevel smallint

SELECT @CurrentIsolationLevel = transaction_isolation_level
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION
-- DO SOME READS AND OTHER THINGS
COMMIT

DECLARE @SQL varchar(200)
SELECT @SQL = 'SET TRANSACTION ISOLATION LEVEL ' +
       CASE  @CurrentIsolationLevel
           WHEN 1 THEN 'READ UNCOMMITTED'
           WHEN 2 THEN 'READ COMMITTED'
           WHEN 3 THEN 'REPEATABLE READ'
           WHEN 4 THEN 'SERIALIZABLE'
           WHEN 5 THEN 'SNAPSHOT'
       END
EXEC (@sql)
like image 22
gbn Avatar answered Oct 20 '22 04:10

gbn