Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IsolationLevel.Snapshot but DB is still locking

I'm part of a team building an ADO.NET based web-site. We sometimes have several developers and an automated testing tool working simultaneously a development copy of the database.

We use snapshot isolation level, which, to the best of my knowledge, uses optimistic concurrency: rather than locking, it hopes for the best and throws an exception if you try to commit a transaction if the affected rows have been altered by another party during the transaction.

To use snapshot isolation level we use:

ALTER DATABASE <database name>
SET ALLOW_SNAPSHOT_ISOLATION ON;

and in C#:

Transaction = SqlConnection.BeginTransaction(IsolationLevel.Snapshot);

Note that IsolationLevel Snapshot isn't the same as ReadCommitted Snapshot, which we've also tried, but are not currently using.

When one of the developers enters debug mode and pauses the .NET app, they will hold a connection with an active transaction while debugging. Now, I'd expect this not to be a problem - after all, all transactions are using snapshot isolation level, so while one transaction is paused, other transactions should be able to proceed normally since the paused transaction isn't holding any locks. Of course, when the paused transaction completes, it is likely to detect a conflict; but that's acceptable so long as other developers and the automated tests can proceed unhindered.

However, in practice, when one person halts a transaction while debugging, all other DB users attempting to access the same rows are blocked despite using snapshot isolation level.

Does anybody know why this occurs, and/or how I can achieve true optimistic (non-blocking) concurrency?

The resolution (an unfortunate one for me): Remus Rusanu noted that writers always block other writers; this is backed up by MSDN - it doesn't quite come out and say so, but only ever mentions avoiding reader-writer locks. In short, the behavior I want isn't implemented in SQL Server.

like image 670
Eamon Nerbonne Avatar asked Jun 25 '09 14:06

Eamon Nerbonne


People also ask

Does snapshot isolation prevent deadlocks?

Snapshot isolation probably will fix the deadlocks, but you do need to check and make sure it will not break any code.

How can I tell if read snapshot is committed?

To check the current state of Read-Committed Snapshot, open a query window and execute the following command: select is_read_committed_snapshot_on from sys. databases where name= 'CitrixSiteDB'; A value of 1 indicates that Read-Committed Snapshot is already enabled and no change is required.

Is snapshot isolation enabled?

You need to enable snapshot isolation by setting the ALLOW_SNAPSHOT_ISOLATION database option in order to use it. The READ_COMMITTED_SNAPSHOT database option determines the behavior of the default READ COMMITTED isolation level when snapshot isolation is enabled in a database.

What is the difference between read committed snapshot and read committed?

This is one of the key differences between SNAPSHOT and READ COMMITTED (READ_COMMITTED_SNAPSHOT is ON) isolation levels and guarantees a higher level of isolation. As it is mentioned above in this article, this behavior can be changed using locking instead of row versioning even in the SNAPSHOT isolation level.


1 Answers

SNAPSHOT isolation level affects, like all isolation levels, only reads. Writes are still blocking each other. If you believe that what you see are read blocks, then you should investigate further and check out the resource types and resource names on which blocking occurs (wait_type and wait_resource in sys.dm_exec_requests).

I wouldn't advise in making code changes in order to support a scenario that involves developers staring at debugger for minutes on end. If you believe that this scenario can repeat in production (ie. client hangs) then is a different story. To achieve what you want you must minimize writes and perform all writes at the end of transaction, in one single call that commits before return. This way no client can hold X locks for a long time (cannot hang while holding X locks). In practice this is pretty hard to pull off and requires a lot of discipline on the part of developers in how they write the data access code.

like image 150
Remus Rusanu Avatar answered Sep 24 '22 06:09

Remus Rusanu