前几天看过数据库锁的介绍,当时虽说看完了,似懂非懂,还记得有次笔试题目,估计也错了,
最近看过高并发性的数据维护课程后,现在翻看锁基础,豁然开朗,现整理笔记,及个人理解
SQL2005锁隔离级别有4种,Read UnCommit ,Read Commit,Repeatable Read 可重复读,
serializable 串行读,
Read UnCommit:读未提交,与nolock一样,允许脏读数据,其中nolock查询执行不发出共享锁,
与其他操作可共存
Read Commit:读提交级别,不会产生脏读,但产生不可重复读,,如果一个事务里面两次读取同一结果集,
在两次读取中间被更改的话,两次读取结果会不同,不会锁住其他更新,
Repeatable Read:能达到重复读取数值,但不能解决其他操作插入,删除表的值,造成幻影现象,
其他操作要等到重复读锁完成,事务提交后,才能进行更新,删除,插入操作,但可以查寻
Serializable: 可串行读,是锁定要求最高的级别,其他操作的查询,更新,等操作都不能进行,
直到该级别操作 完成,事务提交
几种类型: holdlock,选项保持住锁,即使查询完成也不释放,相当于保存共享S锁,
tablocks,独占锁,Nolock 不发出共享锁
rowlock,行锁,pageLock 页锁,tablock 表锁,uplock,更新锁
共享锁=S锁,更新锁=U锁,排它锁=X锁,意向共享锁=IS锁,意向更新锁=IU锁,意向排它共享锁=SIX锁
架构锁=Sch-s
锁的粒度:
1:行锁
2:页锁
3:键:
4:扩展盘区
5:表,数据库
设置锁级别语句:
Set Transaction IsOlation level Read Commit
黏贴测试例子:
1 如何锁一个表的某一行
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM table ROWLOCK WHERE id = 1
2 锁定数据库的一个表
SELECT * FROM table WITH (HOLDLOCK)
加锁语句:
sybase:
update 表 set col1=col1 where 1=0 ;
MSSQL:
select col1 from 表 (tablockx) where 1=0
oracle:
LOCK TABLE 表 IN EXCLUSIVE MODE ;
加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁
几个例子帮助大家加深印象
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
1)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran
若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒
2)共享锁
在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran
若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个事务释放共享锁转为排它锁后才能执行 即要等待30秒
3)死锁
增设table2(D,E)
D E
d1 e1
d2 e2
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二个连接中执行以下语句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran
同时执行,系统会检测出死锁,并中止进程