`

数据库隔离级别

    博客分类:
  • db
阅读更多

ANSI/ISO SQL定义的标准隔离级别有四种,从高到底依次为:可序列化(Serializable)、可重复读(Repeatable reads)、提交读(Read committed)、未提交读(Read uncommitted)。

 

如果处理不好就会产生脏读不可重复读或者幻读等读现象。

 

数据库采用锁的机制才实现这四种隔离级别

以mysql为例,数据库分为表级锁,行级锁,这两种锁又可以细分为表读锁,表写锁,行读锁,行写锁, 简单说就是表锁会锁住整个表,行锁锁住指定的行, 获取读锁的时候其他事务仍然可以获取此读锁,获取写锁之后其他事物只能block知道他释放写锁

 

了解以上之后接下来说明mysql如何利用这些锁来实现隔离级别以避免脏读,不可重复读,幻读

1. 读未提交

    读未提交是因为一个事务读取了到另外一个事务的还没有提交的数据,这在大部分的业务上面都是不允许的,之所以能读取到其他事务还没有commit的数据是因为:

    事务1在读数据的时候没有加任何锁,修改数据的时候也只是加了行级别的读锁

这就导致事务2的事务进行(还没有提交)的过程中可以修改某些事务1已经读取到的数据,因为事务2修改的时候也只是加了读锁,这样事务1再次读取的时候就可以读取到那些修改过的数据,这就是幻读

 

2. 读已提交

    这个和1不同就是,事务1读数据的时候加读锁,读完就释放,更新数据的时候加写锁,事务完成之后再释放,正是因为事务1读完某行数据就释放了锁,然后事务2就可以更新那些数据,所以事务1再次读取的时候数据就不同了,这就是不可重复读

 

3.可重复读

    这个和2不同的就是,事务1读数据的时候加读锁,读完不会释放,等到事务1结束的时候才释放,那么其他事务就不能在这个过程中获得写锁,这样事务1就可以重复读取到一样的数据,但是还是会出现幻读,因为其他事务可以insert数据,这个是行锁不能避免的

 

4.可序列话

   事务在读取数据时,对其加 表级读锁 ,直到事务结束才释放;
   事务在更新数据时,对其加 表级写锁 ,直到事务结束才释放。

这样某一事务在读取数据的过程中,其他事务都不能对相关表进行修改,也就不会发生幻读

 

另外需要理解的是,你更新了数据即便没有commit,数据也是真实的改变了,只不过没有永久的save,这个时候可以rollback,所以才有了未提交读。

 

 

ps:

http://www.hollischuang.com/archives/943
http://www.hollischuang.com/archives/923
http://www.hollischuang.com/archives/914

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics