事务隔离级别与锁机制的实现

来源:互联网 发布:javascript插件dll 编辑:程序博客网 时间:2024/05/21 18:38

一、事务隔离级别与锁机制的的实现

      1。数据库锁的一些概念,大概总结下就是:

      1.1 从锁的策略来分:悲观锁和乐观锁

      悲观锁即很悲观的认为,每次操作数据过程中,都会被别人修改,然后每次都加个锁。一般由数据自身的锁机制实现,比如数据库的事务隔离级别就是一系列锁机制的组合,当然还可以手动加锁。

      乐观锁 : 就是很乐观的认为别人不会修改,不加锁,但是在更新提交的时候,就会判断一下别人会不会修改这个数据,比如说:我给表加一个字段更新时间/更新次数,提交的时候带着这个字段判断下是否数据被修改,修改就不进行更新的提交。

        1.2  从锁的读写角度来分:共享锁和排它锁

     排他锁(X) 被加锁的对象只能被持有锁的事务读取和修改,其他事务无法在该对象上加其他锁,也不能读取和修改该对象

     共享锁(S) 被加锁的对象可以被持锁事务读取,但是不能被修改,其他事务也可以在上面再加共享锁。

      细节:共享锁可以在一个数据库对象中加多次,比如A事务和B事务在默认事务级别可以随便读(默认事务级别读数据加的是共享锁),这被称为共

享锁与共享锁兼容。但是,如果其中一个事务还想修改(默认事务写修改加的是排它锁),就需要其他的事务释放拿到的共享锁。
      1.3   从锁的控制粒度来分: 行级锁和表级锁

       这很容易理解,比如默认事务级别下,update table set name = xx where id = 1 这里就是加了id=1的此行行级排它锁。而不加这个条件,就属于表级排它锁。


   2 数据库的四种隔离级别的回顾

       
隔离级别                                                                 产生的意外

read uncommitted脏读、不可重复读、幻读都可以发生read committed不可重复读、幻读可以发生repeatable read幻读有可能发生serializable  全灭

意外情况的说明:

2.1  脏读  : A事务读到B未提交数据   ----举例:B存100,还没结束事务,A就读到了B的结果。

2.2  不可重复读:  A读到B的已提交Update语句   -------举例 : B修改了一条数据,A再此前后都读取此数据,就能重复读到不一样结果。

2.3  幻读:A读到B的已提交insert语句   ------举例: B插入了一条数据提交了,A再次读取整个表,数据多了一条。

 

      3。数据库的这四种隔离级别对应的具体锁机制是这么样的呢?  (以下为个人揣测改编)

1、一级锁协议(read uncommited) 

      首先:我们想想,一级会产生所有的意外情况,连没提交事务都能被另外一个事务读取到,说明,它加的不是排它锁,如果是排它锁的话,其他事务是不能操作的,所以就分析出,它应该是给修改加的是共享锁才会出现这个情况。(比如:我给A事务修改加共享锁,B事务查询加的也是共享锁,那么A修改没提交事务,B事务就能看到).

     一级锁协议不能避免 丢失更新,脏读,不可重复读,幻读!

2、二级锁协议(read commited)
 
       首先,我们解决上面脏读的问题,如果我给修改加上排它锁,那么就不会出现这个问题了,但是,根据2.2的描述,A先读取一个数据,B修改,A再读,要读到不一样的数据。而如果A读取数据第一次后,不释放共享锁,B是得不到排它锁的,所以这里除了给修改加排它锁,还要给读取按每一条SQL加共享锁,才能实现上面的效果。

       二级锁协议防止了脏读,但是不能避免 丢失更新,不可重复读,幻读 。

       说明下丢失更新的理解:比如:A,B事务都读到同一个资源,A事务把资源修改了,B事务也把资源修改了,那么那个先提交的修改就无效了,因为后提交也是拿到一样的资源,你修改了,它并不知道。如何防止这种呢? 这个往往需要程序员自己编程实现,比如在oracle中,需要加 SELECT FOR UPDATE 语句


3、三级锁协议(repeatable read)


     三级锁协议,就是碰到事务含更新就加上一个排它锁,如果是查询就增加共享锁,案例: A事务读数据,A拿到共享锁,B想修改,但是A不释放锁,所以B就无法拿到排它锁,因此A事务2次过程中都不释放共享锁,别人就是无法修改的。(扩展:这里出现一个问题,A查询拿到一个共享锁,B查询拿到共享锁,如果A,B都想修改,那么是会发生死锁的,所以,我认为,这里的读取应该加的是行级排它锁或其他机制实现的,细节不究了。)

    repeatable read 是无法规避幻读的,因为锁的数据是行级,而幻读是此表增加一个数据. 案例描述: A事务查询某行数据,增加了行级排它锁,B事务增加一条数据,A再次查询就能读到增加的这条数据。

     三级封锁协议除防止了脏读 不可重复读,但是不能避免 幻读 。

 

4、最强锁协议(对应Serialization)

      对事务中所读取或者更改的数据所在的表加表锁,也就是说,其他事务不能读写该表中的任何数据。这样所有的 脏读,不可重复读,幻读 ,都得以避免!

原创粉丝点击