数据库:事务隔离级别

数据库事务需要满足ACID特性,即原子性、一致性、隔离性和持久性。对于隔离级别,SQL标准定义了四种隔离级别:Read Uncommitted、Read Committed、Repeatable Read和Serializable。隔离级别依次增强。隔离级别越高,事务请求的锁越多或者保持锁的时间就越长,并发性就越低。所以数据库的默认级别一般不是在最高级别的Serializable。Oracle数据库的默认隔离级别是Read Committed而innodb的默认级别是Repeatable Read。

Read Uncommitted

隔离级别最低,可以读取其他事务没有提交的数据。比如,事务A执行如下操作,update t set b = 2 where a = 1;但是不提交。事务B执行select b from t where a = 1;这个时候事务B中读取的b为2。此时事务A回滚,b的实际值就变成了1。之前事务B中看到的数据就成了脏数据,这就是脏读。

数据库:事务隔离级别

脏读例子

Read Committed

可以读取其他事务已经提交的数据。在这种级别下,可以避免脏读,但是不能避免不可重复读。比如,一张表t,包含列(a, b),有一条数据(1, 1)。事务A执行:select b from t where a = 1;读取到B为1。此时事务B执行:update t set b = 2 where a = 1;并且事务B提交。这个时候,在事务A中再次执行select b from t where a = 1;查出来的数据b却变成了2。这就是不可重复读。与脏读相比,不可重复读,读到的数据是已经提交的数据,是真实的数据,脏读读到的是脏数据。

数据库:事务隔离级别

不可重复读例子

Repeatable Read

可重复读,可以避免不可重复读,但是不能避免幻读。什么是幻读呢?请看例子。一张表t,包含列(a, b),有一条数据(1, 1)。事务A执行:select count(*) from t where a > 0;此时,得到的结果是1。事务B执行insert into t (a, b) values(2, 2);事务B提交。此时事务A中再次执行select count(*) from t where a > 0;时,等到的结果变成了2。这就是幻读。与不可重复读相比,幻读是针对范围的,不可重复读是针对单条记录的。

数据库:事务隔离级别

幻读例子

Serializable

是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。

对于innodb而言,默认是Repeatable Read,但是由于其采用的next key锁,所以在这个级别下也能避免幻读。next key锁是什么呢?是gap锁加单行记录锁。单行记录锁在单个行记录上加锁。gap锁是区间锁,锁定一个范围,但是不包含记录本身。next key锁就是这两种锁的结合体。

各隔离级别整体情况如下:

数据库:事务隔离级别

各隔离级别情况


分享到:


相關文章: