Cause a deadlock

shorter duration than a higher isolation level, such as. This reduces lock

contention.

When the

database option is set

, a transaction running under the

isolation level uses row versioning rather than shared locks during read

operations.

Snapshot isolation also uses row versioning, which doesn’t use shared locks during read

operations. Before a transaction can run under snapshot isolation, the

database option must be set.

Use row versioning-based isolation levels to minimize deadlocks that can occur between read

and write operations.

Using bound connections, two or more connections opened by the same application can

cooperate with each other. Any locks acquired by the secondary connections are held as if they

were acquired by the primary connection, and vice versa. Therefore, they don’t block each

other.

You might need to cause a deadlock for learning or demonstration purposes.

The following example works in the

sample database with the default

schema and data when

READ_COMMITTED_SNAPSHOT has been enabled. To download this

sample, visit

AdventureWorks sample databases.

For an example that causes a deadlock when optimized locking is enabled, see

Optimized

locking and deadlocks.

Tip

Microsoft recommends the row versioning-based

isolation level for all

applications, unless an application relies upon the blocking behavior of the lock-based

isolation level.

Session A

Session B

Session A

Session B

Session B

Session A

Session B

Session A

To cause a deadlock, you need to connect two sessions to the

database.

We refer to these sessions as

and. You can create these two sessions by

creating two query windows in SQL Server Management Studio (SSMS).

In

, run the following batch. This code begins an

explicit transaction

and executes a

statement that updates the

table. To do this, the transaction acquires an

update (U) lock

on the qualifying rows in table

which are then converted to

exclusive (

) locks. We leave the transaction open.

Now, in

, run the following batch. This code doesn’t explicitly begin a transaction.

Instead, it operates in

autocommit transaction mode. This statement updates the

table. The update takes an update (

) lock on the qualifying rows

in the

table. The query joins to other tables, including the

table.

To complete this update,

needs shared (

) locks on rows in table

,

including the rows that are locked by.

is blocked on.

Return to. Run the following

statement. This statement executes as a part of

the previously open transaction.

SERIALIZABLE

READ_COMMITTED_SNAPSHOT

ON

READ COMMITTED

ALLOW_SNAPSHOT_ISOLATION

ON

AdventureWorksLT2019

READ COMMITTED
READ COMMITTED

AdventureWorksLT2019

SalesLT.Product

SalesLT.Product

X

SalesLT.ProductDescription

U

SalesLT.ProductDescription

SalesLT.Product

S

SalesLT.Product

SalesLT.Product

UPDATE

BEGIN
TRANSACTION
;
UPDATE
SalesLT.Product
SET
SellEndDate = SellEndDate + 1
WHERE
Color =
'Red'
;
UPDATE
SalesLT.ProductDescription
SET
Description = Description
FROM
SalesLT.ProductDescription
AS pd
INNER
JOIN
SalesLT.ProductModelProductDescription
AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER
JOIN
SalesLT.ProductModel
AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER
JOIN
SalesLT.Product
AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color =
'Silver'
;
UPDATE
SalesLT.ProductDescription
SET
Description = Description