IF EXISTS( SELECT 1
FROM sys.views
WHERE name = 'DBlocks')
DROP VIEWDBlocks;
GO
CREATE VIEW DBlocksAS
SELECT request_session_idASspid,
DB_NAME(resource_database_id) ASdbname ,
CASEWHEN resource_type ='OBJECT'
THEN OBJECT_NAME(resource_associated_entity_id)
WHEN resource_associated_entity_id=0 THEN 'n/a'
ELSE OBJECT_NAME(p.object_id)
END ASentity_name ,
index_id,
resource_type ASresource ,
resource_descriptionASdescription,
request_modeASmode ,
request_statusASstatus
FROM sys.dm_tran_lockst
LEFT JOIN sys.partitionsp
ON p.partition_id=t.resource_associated_entity_id
WHERE resource_database_id=DB_ID()
ANDresource_type <>'DATABASE' ;
GO
-- Example 1: SELECT withREAD COMMITTED
-- isolationlevel
USE General;
SET TRANSACTION ISOLATION LEVELREADCOMMITTED ;
BEGIN TRAN
SELECT *
FROM dbo.GenderNG
WHERE gendername ='Reflector';
SELECT *
FROM DBlocks
WHERE spid= @@spid;
COMMIT TRAN
/*There are nolockson the data in the Production.Producttable because the batch
was doingonlySELECT operations,andso acquiredonlySlocks.By default,SQLServer
releasesSlocksassoon as ithas finishedreadingthe dataso,by the time we execute
the SELECT fromthe view,SQLServerno longerholdsthe locks.
*/
-- Example 2: SELECT withREPEATABLE READ
-- isolationlevel
USE General ;
SET TRANSACTION ISOLATION LEVELREPEATABLEREAD ;
BEGIN TRAN
SELECT gendername,sex
FROM dbo.GenderNG
WHERE gendername LIKE'Ana%';
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='GenderNG';
COMMIT TRAN
/*
Thistime,because the transactionisolationlevelisREPEATABLEREAD,SQL Serverholds
the S locksuntil the transactionisfinishedandsowe can see theminour results.The
dbo.GenderNGtable hasaclusteredindex,sothe rowsof data are all index rows
inthe leaf level.Assuch,the locksonthe 19 individual datarows
returnedare KEY locks.The table alsohas a non-clusteredindexonthe genderNamecolumn
and we can see 19 KEY locksat the leaf level of thisnon-clusteredindex,usedtofindthe
relevantrows.
*/
-- Example 3: SELECT withSERIALIZABLEisolation
-- level
USE General ;
SET TRANSACTION ISOLATION LEVELSERIALIZABLE;
BEGIN TRAN
SELECT *
FROM dbo.GenderNG
WHERE gendername LIKE'Ana%';
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='GenderNG';
COMMIT TRAN
/*
The two-partmode RangeS-Sindicatesakey-range lockinadditiontothe lockon the
keyitself.The firstpart(RangeS) isthe lockonthe range of keysbetweenandincluding
the keyholdingthe lockandthe previouskeyinthe index.The key-rangelocksprevent
othertransactionsfrominsertinganynew rowsintothe table thatmeetthe conditionof
thisquery;that is,it'snot possible toinsertanynew rowswithaproduct name starting
withRacingSocks.The key-range locksare heldonrangesinthe non-clusteredindex
on gendername (Index_id=3) because thatisthe index usedtofindthe qualifyingrows.
*/
-- Example 4: Update withREAD COMMITTED
-- isolationlevel
USE General ;
SET TRANSACTION ISOLATION LEVELREADCOMMITTED ;
BEGIN TRAN
UPDATE dbo.GenderNG
SET Sex = 1
WHERE gendername LIKE'Adam%';
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='GenderNG';
COMMIT TRAN
/*
the two rowsinthe leaf level of the clusteredindex are lockedwith
X locks.The page and the table are thenlockedwithIXlocks.
As discussedearlier,SQLServeracquiresUlockswhile itlooksforthe rowsto update.
However,SQLServerescalatesthese toXlocksuponperformingthe actual update and,
by the time we lookat the DBlocksview,the U locksare gone.Unlesswe force U locks
witha queryhint,we mightneversee theminthe lockreportfromDBlocks,or by direct
inspectionof sys.dm_tran_locks.
*/
-- Example 5: Update withSERIALIZABLEisolation
-- level (withanindex)
USE General ;
SET TRANSACTION ISOLATION LEVELSERIALIZABLE
BEGIN TRAN
UPDATE dbo.GenderNG
SET Sex = 1
WHERE gendername LIKE'Adam%';
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='GenderNG';
COMMIT TRAN
/*
Again,notice thatthe key-range locksare onthe non-clusteredindex,usedtofindthe
relevantrows.The range interval itself needsonlyanSlockto preventinsertions,but
the searchedkeyshave U locks,ensuringthatnootherprocesscan attempttoUPDATE
them.The keysinthe table itself (index_id=1) obtainthe X lockwhenthe actual
modificationismade.
*/
-- Example 6: Update withSERIALIZABLEisolation
-- level notusinganindex
USE General ;
SET TRANSACTION ISOLATION LEVELSERIALIZABLE
BEGIN TRAN
UPDATE dbo.GenderNG
SET Sex = 1
WHERE Sex = 2 ;
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='GenderNG';
COMMIT TRAN
/*
As there wasno useful index,aclusteredindexscanonthe entire table wasrequired,
and so all keysinitiallyreceivedthe RangeS-Ulock;whenfourrowswere eventually
modified,the locksonthose keysescalatedtothe RangeX-Xlock.We cansee twoof
the RangeX-Xlocks,anda fewof the RangeS-Ulocks.The complete outputhas501
RangeS-Ulocks,as well asIU lockson several pages,IXlocksontwopages,and an IX
lockon the table.
*/
-- Example 7: Creatinga table
USE General ;
SET TRANSACTION ISOLATION LEVELREADCOMMITTED ;
BEGIN TRAN
SELECT *
INTO newGender
FROM dbo.GenderNG
WHERE Sex BETWEEN 1 AND 2 ;
SELECT *
FROM DBlocks
WHERE spid= @@spid;
COMMIT TRAN
/*
SQL Serveracquiredveryfewof these locksonelementsof the
newGendertable.Inthe entity_name column,note thatmostof the objectsare
undocumented,andnormallyinvisible,systemtable names.Whencreatingthe new table,
SQL Serveracquireslocksonsix differentsystemtablestorecordinformationabout
thisnewtable.Inaddition,notice the schemamodification(Sch-M) locks
*/
-- Example 8: RID locks
USE General ;
SET TRANSACTION ISOLATION LEVELREADCOMMITTED
BEGIN TRAN
UPDATE newGender
SET Sex = 1
WHERE genderName ='Alan';
SELECT *
FROM DBlocks
WHERE spid= @@spid
ANDentity_name ='newGender';
COMMIT TRAN
/*
There are noindexesonthe newProductstable,sothe lockonthe actual row meeting
our criterionisan Xlock on the row(RID).For RID locks,the descriptionactuallyreports
the specificrowinthe form File Number:Page number:Slotnumber.Asexpected,SQL
ServertakesIXlockson the page and the table.
*/

Transaction isolationexamples

  • 1.
    IF EXISTS( SELECT1 FROM sys.views WHERE name = 'DBlocks') DROP VIEWDBlocks; GO CREATE VIEW DBlocksAS SELECT request_session_idASspid, DB_NAME(resource_database_id) ASdbname , CASEWHEN resource_type ='OBJECT' THEN OBJECT_NAME(resource_associated_entity_id) WHEN resource_associated_entity_id=0 THEN 'n/a' ELSE OBJECT_NAME(p.object_id) END ASentity_name , index_id, resource_type ASresource , resource_descriptionASdescription, request_modeASmode , request_statusASstatus FROM sys.dm_tran_lockst LEFT JOIN sys.partitionsp ON p.partition_id=t.resource_associated_entity_id WHERE resource_database_id=DB_ID() ANDresource_type <>'DATABASE' ; GO
  • 2.
    -- Example 1:SELECT withREAD COMMITTED -- isolationlevel USE General; SET TRANSACTION ISOLATION LEVELREADCOMMITTED ; BEGIN TRAN SELECT * FROM dbo.GenderNG WHERE gendername ='Reflector'; SELECT * FROM DBlocks WHERE spid= @@spid; COMMIT TRAN /*There are nolockson the data in the Production.Producttable because the batch was doingonlySELECT operations,andso acquiredonlySlocks.By default,SQLServer releasesSlocksassoon as ithas finishedreadingthe dataso,by the time we execute the SELECT fromthe view,SQLServerno longerholdsthe locks. */ -- Example 2: SELECT withREPEATABLE READ -- isolationlevel
  • 3.
    USE General ; SETTRANSACTION ISOLATION LEVELREPEATABLEREAD ; BEGIN TRAN SELECT gendername,sex FROM dbo.GenderNG WHERE gendername LIKE'Ana%'; SELECT * FROM DBlocks WHERE spid= @@spid ANDentity_name ='GenderNG'; COMMIT TRAN /* Thistime,because the transactionisolationlevelisREPEATABLEREAD,SQL Serverholds the S locksuntil the transactionisfinishedandsowe can see theminour results.The dbo.GenderNGtable hasaclusteredindex,sothe rowsof data are all index rows inthe leaf level.Assuch,the locksonthe 19 individual datarows returnedare KEY locks.The table alsohas a non-clusteredindexonthe genderNamecolumn and we can see 19 KEY locksat the leaf level of thisnon-clusteredindex,usedtofindthe relevantrows. */ -- Example 3: SELECT withSERIALIZABLEisolation -- level
  • 4.
    USE General ; SETTRANSACTION ISOLATION LEVELSERIALIZABLE; BEGIN TRAN SELECT * FROM dbo.GenderNG WHERE gendername LIKE'Ana%'; SELECT * FROM DBlocks WHERE spid= @@spid ANDentity_name ='GenderNG'; COMMIT TRAN /* The two-partmode RangeS-Sindicatesakey-range lockinadditiontothe lockon the keyitself.The firstpart(RangeS) isthe lockonthe range of keysbetweenandincluding the keyholdingthe lockandthe previouskeyinthe index.The key-rangelocksprevent othertransactionsfrominsertinganynew rowsintothe table thatmeetthe conditionof thisquery;that is,it'snot possible toinsertanynew rowswithaproduct name starting withRacingSocks.The key-range locksare heldonrangesinthe non-clusteredindex on gendername (Index_id=3) because thatisthe index usedtofindthe qualifyingrows. */ -- Example 4: Update withREAD COMMITTED -- isolationlevel
  • 5.
    USE General ; SETTRANSACTION ISOLATION LEVELREADCOMMITTED ; BEGIN TRAN UPDATE dbo.GenderNG SET Sex = 1 WHERE gendername LIKE'Adam%'; SELECT * FROM DBlocks WHERE spid= @@spid ANDentity_name ='GenderNG'; COMMIT TRAN /* the two rowsinthe leaf level of the clusteredindex are lockedwith X locks.The page and the table are thenlockedwithIXlocks. As discussedearlier,SQLServeracquiresUlockswhile itlooksforthe rowsto update. However,SQLServerescalatesthese toXlocksuponperformingthe actual update and, by the time we lookat the DBlocksview,the U locksare gone.Unlesswe force U locks witha queryhint,we mightneversee theminthe lockreportfromDBlocks,or by direct inspectionof sys.dm_tran_locks. */ -- Example 5: Update withSERIALIZABLEisolation -- level (withanindex)
  • 6.
    USE General ; SETTRANSACTION ISOLATION LEVELSERIALIZABLE BEGIN TRAN UPDATE dbo.GenderNG SET Sex = 1 WHERE gendername LIKE'Adam%'; SELECT * FROM DBlocks WHERE spid= @@spid ANDentity_name ='GenderNG'; COMMIT TRAN /* Again,notice thatthe key-range locksare onthe non-clusteredindex,usedtofindthe relevantrows.The range interval itself needsonlyanSlockto preventinsertions,but the searchedkeyshave U locks,ensuringthatnootherprocesscan attempttoUPDATE them.The keysinthe table itself (index_id=1) obtainthe X lockwhenthe actual modificationismade. */ -- Example 6: Update withSERIALIZABLEisolation -- level notusinganindex USE General ; SET TRANSACTION ISOLATION LEVELSERIALIZABLE
  • 7.
    BEGIN TRAN UPDATE dbo.GenderNG SETSex = 1 WHERE Sex = 2 ; SELECT * FROM DBlocks WHERE spid= @@spid ANDentity_name ='GenderNG'; COMMIT TRAN /* As there wasno useful index,aclusteredindexscanonthe entire table wasrequired, and so all keysinitiallyreceivedthe RangeS-Ulock;whenfourrowswere eventually modified,the locksonthose keysescalatedtothe RangeX-Xlock.We cansee twoof the RangeX-Xlocks,anda fewof the RangeS-Ulocks.The complete outputhas501 RangeS-Ulocks,as well asIU lockson several pages,IXlocksontwopages,and an IX lockon the table. */ -- Example 7: Creatinga table USE General ; SET TRANSACTION ISOLATION LEVELREADCOMMITTED ; BEGIN TRAN SELECT *
  • 8.
    INTO newGender FROM dbo.GenderNG WHERESex BETWEEN 1 AND 2 ; SELECT * FROM DBlocks WHERE spid= @@spid; COMMIT TRAN /* SQL Serveracquiredveryfewof these locksonelementsof the newGendertable.Inthe entity_name column,note thatmostof the objectsare undocumented,andnormallyinvisible,systemtable names.Whencreatingthe new table, SQL Serveracquireslocksonsix differentsystemtablestorecordinformationabout thisnewtable.Inaddition,notice the schemamodification(Sch-M) locks */ -- Example 8: RID locks USE General ; SET TRANSACTION ISOLATION LEVELREADCOMMITTED BEGIN TRAN UPDATE newGender SET Sex = 1 WHERE genderName ='Alan'; SELECT * FROM DBlocks
  • 9.
    WHERE spid= @@spid ANDentity_name='newGender'; COMMIT TRAN /* There are noindexesonthe newProductstable,sothe lockonthe actual row meeting our criterionisan Xlock on the row(RID).For RID locks,the descriptionactuallyreports the specificrowinthe form File Number:Page number:Slotnumber.Asexpected,SQL ServertakesIXlockson the page and the table. */