When using snapshot isolation, why do I often see IF ##TRANCOUNT = 0 before setting the transaction level?
I.e., in a stored proc:
IF ##TRANCOUNT = 0
BEGIN
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
END
one reason is this from Microsoft Documentations:
A transaction cannot be set to SNAPSHOT isolation level that started with another isolation level; doing so will cause the transaction to abort. If a transaction starts in the SNAPSHOT isolation level, you can change it to another isolation level and then back to SNAPSHOT. A transaction starts the first time it accesses data.
Related
I have read that serializable isolation level blocks only: insert, update, delete but NOT read.
I have run in one window:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE [dbo].[Categories]
SET name = 'aaa'
WHERE categoryid = 4;
-- without commit
And in the second window:
SELECT TOP (1000) [CategoryId]
,[Name]
FROM [dbo].[Categories]
And the above query is waiting for the end of the first query. So does serialization isolation level block also read?
Yes it blocks reads. Your transaction is not committed, so you can still do a rollback. That means the data you have updated should not be read by any other process before you commit.
"does serialization isolation level block also read" : No.
Serializable acquires some lock (in Ms Sql its shared lock + range lock) which prevents writes from other transactions.
Its the UPDATE statement's exclusive lock (the above shared lock now converts to exclusive lock) that prevents second transaction's SELECT (Read Commited or Repeatable Read by deafult depending on db) to wait.
If I'm using
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Do I need to wrap the query in a transaction
e.g.
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM
T1
COMMIT
Or can I just have a normal query?
Also, is there any benefit to including SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED and WITH (NOLOCK). I understand that one is for the table level and one is for the whole connection level. But is there any benefit to having both?
Such as:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM
T1 WITH (NOLOCK)
Always we executes procedure of INSERT, UPDATE and DELETE transaction with READ COMMITTED ISOLATION LEVEL. If we need dirty data from any table then it helps. Because Transaction is defined with READ COMMITTED and table return dirty reads using WITH(NOLOCK) in JOIN Query.
You don't need to wrap the query below in a transaction:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Because even if wrapping the query above in a transaction as shown below, isolation level is still set on session(connection) level but not on transaction level:
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
COMMIT
So, even if rollbacking isolation level as shown below, isolation level is not rollbacked so it's still READ UNCOMMITTED but not READ COMMITTED.
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
ROLLBACK -- Isolation level is still "READ UNCOMMITTED" but not "READ COMMITTED"
I am trying to update table, which controlls application (application performs some select statements). I would like to update the table in transaction with isolation level set to read uncommited, so if application doesn't work as expected I can rollback transactions.
But following code doesn't work:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
go
begin transaction
go
update [DB].[dbo].[Table]
set ID = ID - 281
where ID > 2
When I open another query window, I cannot query this table... I thought, that with such transaction level I would be able to query the table without rolling back/commiting transaction.
Isolation level works in another way as you suppose.
You can only read uncommitted data, but others still cannot see what you done within transaction until you commit.
If you want to see uncommitted data from this transaction in your select you need to set
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
to this select
You need to use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED from a session which reads data.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT *
FROM [DB].[dbo].[Table]
This query will execute immediately without lock. And you'll see the dirty data.
Consider the following SQL statement:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
insert into Customer(name)
values('CustomerName')
COMMIT
Am I right in saying this Isolation Level is not needed since we are doing a simple insert? Not actually READing anything
Once you alter database to use Read Commited Snapshot isolation level, OR snapshot isolation level
Do all transaction now uses that isolation as default or Read Commited is stil the default isolation level and you have to change all stored proc to use by specifying
SET TRANSACTION ISOLATION LEVEL Read_committed_snapshot to use Read Committed Snapshot
The entire database and code and transaction all use whatever your setting us
Unless you set SET TRANSACTION ISOLATION LEVEL in the code somewhere separately...