数据库并发访问

数据库的并发访问会引起丢失修改、不可重复读和读数据3种问题。
    
丢失修改是指一事务的修改数据尚未提交,而另一事务又将该未提交修改的数据做了再次修改。例如,两个编辑人员制作了同一文档的电子复本。每个编辑人员独立地更改其复本,然后保存更改后的复本,这样就覆盖了原始文档。最后保存其更改复本的编辑人员覆盖了第一个编辑人员所做的更改。
    
不可重复读是指事务T1读取数据后,事务T2执行更新操作,是T1无法再现前一次读取结果。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。
    
数据是指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这是T1已修改过的数据恢复原始值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据九位数据,即不正确的数据。例如,一个编辑人员正在更改电子文档。在更改过程中,另一个编辑人员复制了该文档(该复本包含到目前为止所做的全部更改)并将其分发给预期的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所做的编辑并保存了文档。分发给用户的文档包含不再存在的编辑内容,并且这些编辑内容应认为从未存在过。
    
为避免并行事务操作出现上述问题,DBMS在进行并发控制时,为保证事务的可串行化执行,采用了基于锁的并发控制协议。
    
所谓封锁就是事务T再多某个数据对象操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新次数据的对象。
    
基本的封锁类型有两种:排他锁和共享锁。
例如:
table1(A,B,C)
A      B      C
a1     b1     c
1
a2     b2     c
2
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'
   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

posted @ 2012-01-07 21:20  刀锋_Master  阅读(315)  评论(0编辑  收藏  举报