数据库的隔离级别

Aug 15, 2016


  脏读 重复读 幻读
读未提交
读提交 ×
重复读 × ×
序列化 × × ×

1、Read Uncommited 读未提交

  可能读到脏数据,即某个事务修改但是还未提交的数据。这个应该是最低的要求了,举个简单例子,小杰老婆查看银行卡余额,发现本应由200只剩100块,很火大,打算找小杰算账。其实小杰只是在美团下单了100元,最终没付确认付款。这里下单是指一个事务的操作,而确认付款是指事务的提交。此时一个线程对事务进行了操作,还并未提交,而另一个线程读取到了未提交的数据。最终小杰放弃付款,小杰老婆白白生气了一场。

2、Read Commit 读提交

  读到的数据都是已经提交的数据,即当前读到的数据可能已经被其他事务修改但是还未提交, 再次读取时可能会出现数据不一致的现象。还是刚才的例子,小杰老婆就会读到200元。如果小杰真的确认付款, 那么老婆再次查看余额就会发现余额变成了100元。两次读取的结果不一致。这就是不可重复读。

3、Reapeatable read 重复读

  一旦A事务开始,事务B就不能对事务A操作的数据行进行修改,即事务A期间多次读取到的结果保证一致。可能出现幻读。一个经典的场景是:一个事务用Where子句来检索一个表的数据,另一个事务插入一条新的记录,并且符合Where条件,这样,第一个事务用同一个where条件来检索数据后,就会多出一条记录。
  还是小杰的例子吧,小杰下单了,这时老婆无法查看余额,因为余额项正在被操作(锁定机制)。但这次老婆查看的是消费明细,即小杰一个月内在玫瑰花园购买优惠券的次数。小杰这次也是在玫瑰花园下单,但是还未确认付款。那么老婆能够查到小杰的这次消费吗?肯定不会呀。那么老婆的操作会被锁定吗?也不会,因为老婆并不是对余额的操作。等到小杰没忍住提交了,老婆的查询统计就是错的,并没有最新的消费记录。这就是幻读。

4、Serializable 序列化

  所有的事务都按顺序执行