数据库事务的4个特性、隔离级别以及脏读, 不可重复读, 幻读

转自:https://blog.csdn.net/sunxing007/article/details/6427290

 

数据库事务的4个特性:

原子性(atomic): 都成功或者都失败;
一致性(consistency):事务操作之后,数据库所处的状态和业务规则是一致的;比如a,b账户相互转账之后,总金额不变;
隔离性(isolation):操作中的事务不相互影响;
持久性(durability):事务提交后被持久化到数据库.

脏读:事务b读取了事务a未提交的内容,事务a回滚,致使事务b读取无效。
不可重复读:事务a在读取数据时,事务b更新(update)该数据并提交,致事务a再次读取时为事务b更新后的记录。
幻读:事务a更新数据但未提交,事务b添加(add)一行新数据,致事务a再次读取时为事务b添加后的记录。

事务隔离级别:

READ UNCOMMITTED(读未提交):幻读,不可重复读和脏读均允许;
READ COMMITTED(读已提交):允许幻读和不可重复读,但不允许脏读;(Oracle默认)
REPEATABLE READ(重复读):允许幻读,但不允许不可重复读和脏读;(MYSQL默认)
SERIALIZABLE(序列化):幻读,不可重复读和脏读都不允许。

原理

REAE_UNCOMMITTED, 其他线程可以看到未提交的数据, 因此会出现脏读;

READ_COMMITTED, 未提交的数据别人是看不见的,避免了脏读;但是,正在读取的数据只获得了读取锁,读完后解锁,不管当前事务有没有结束,这样就容许其他事务修改本事务正在读取的数据。导致不可重复读。

REPEATABLE READ,对正在操作的数据加锁,并且只有等到事务结束才放开锁, 则可以避免不可重复读;只能保证正在被本事务操作的数据不被其他事务修改,却无法保证有其他事务提交新的数据。 则有可能线程1在操作表T1的时候(特别是统计性的事务),其他线程仍然可以提交新数据到表T1,这样会导致线程1两次统计的结果不一致,就像发生幻觉一样。

SERIALIZABLE,因获得范围锁,且事务是一个接着一个串行执行,则保证了不会发生幻读。
因此,隔离级别越高,受其他事物干扰越少,安全性越高,但并发性能越差。

你可能感兴趣的:(数据库)