讲解MSSQL数据库中SQL锁机制和事务隔离级别
锁机制
NOLOCK和READPAST的区别。
1.开启一个事务执行插入数据的操作。
BEGINTRANt
INSERTINTOCustomer
SELECT'a','a'
2.执行一条查询语句。
SELECT*fromCustomerWITH(NOLOCK)
结果中显示"a"和"a"。当1中事务回滚后,那么a将成为脏数据。(注:1中的事务未提交)。NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修改。
SELECT*fromCustomer
这条语句将一直死锁,直到排他锁解除或者锁超时为止。(注:设置锁超时SETLOCK_TIMEOUT1800)
SELECT*fromCustomerWITH(READPAST)
这条语句将显示a未提交前的状态,但不锁定整个表。这个提示指明数据库引擎返回结果时忽略加锁的行或数据页。
3.执行一条插入语句。
BEGINTRANt
INSERTINTOCustomer
SELECT'b','b'
COMMITTRANt
这个时候,即使步骤1的事务回滚,那么a这条数据将丢失,而b继续插入数据库中。
NOLOCK
1.执行如下语句。
BEGINTRANttt
SELECT*fromCustomerWITH(NOLOCK)
WAITFORdelay'00:00:20'
COMMITTRANttt
注:NOLOCK不加任何锁,可以增删查改而不锁定。
INSERTINTOCustomerSELECT'a','b'–不锁定
DELETECustomerwhereID=1–不锁定
SELECT*fromCustomer–不锁定
UPDATECustomerSETTitle='aa'WHEREID=1–不锁定
ROWLOCK
1.执行一条带行锁的查询语句。
SETTRANSACTIONISOLATIONLEVELREPEATABLEREAD--(必须)
BEGINTRANttt
SELECT*fromCustomerWITH(ROWLOCK)WHEREID=17
WAITFORdelay'00:00:20'
COMMITTRANttt
注:在删除和更新正在查询的数据时,会锁定数据。对其他未查询的行和增加,查询数据无影响。
INSERTINTOCustomerSELECT'a','b'–不等待
DELETECustomerwhereID=17–等待
DELETECustomerwhereID<>17–不等待
SELECT*fromCustomer–不等待
UPDATECustomerSETTitle='aa'WHEREID=17–等待
UPDATECustomerSETTitle='aa'WHEREID<>17–不等待
HOLDLOCK,TABLOCK和TABLOCKX
1.执行HOLDLOCK
BEGINTRANttt
SELECT*fromCustomerWITH(HOLDLOCK)
WAITFORdelay'00:00:10'
COMMITTRANttt
注:其他事务可以读取表,但不能更新删除
updateCustomersetTitle='aa'—要等待10秒中。
SEL......