事务的四种隔离级别

事务指定四种类型的隔离级别,隔离程度按照从弱到强分别为
  • Read Uncommitted读未提交
  • Read Committed读已提交
  • Repeatable Read可重复读
  • Serializable串行化
数据不一致的几个体现
  • Dirty Read - 脏读
如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
不可重复读取
  • Non-Repeatable Read - 不可重复读取
是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。
  • Phantom Read - 幻读
幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下, 不管事务2的插入操作是否提交,事务1在插入操作之前和之后执行相同的查询,取得的结果集是不同的,所以,Read Uncommitted同样无法避免幻读的问题。
                                                                                              
Read Uncommitted.  
最低的隔离级别,Read Uncommitted最直接的效果就是一个事务可以读取另一个事务并未提交的更新结果。

Read Uncommitted是以较低的隔离度来寻求较高的性能,其本身无法Dirty Read - 脏读、Non-Repeatable Read - 不可重复读取、Phantom Read - 幻读

Read Committed.  
Read Committed通常是大部分数据库采用的默认隔离级别,它在Read Uncommitted隔离级别基础上所做的限定更进一步, 在该隔离级别下,一个事务的更新操作结果只有在该事务提交之后,另一个事务才可能读取到同一笔数据更新后的结果。 所以,Read Committed可以避免Read Uncommitted隔离级别下存在的脏读问题, 无法避免不可重复读取和幻读的问题。

Repeatable Read.
Repeatable Read隔离级别可以保证在整个事务的过程中,对同一笔数据的读取结果是相同的,不管其他事务是否同时在对同一笔数据进行更新,也不管其他事务对同一笔数据的更新提交与否。 Repeatable Read隔离级别避免了脏读和不可重复读取的问题,但无法避免幻读(MySQL innodb的间隙锁可以避免,但是容易造成性能下降和死锁)

Serializable.
最为严格的隔离级别,所有的事务操作都必须依次顺序执行,可以避免其他隔离级别遇到的所有问题,是最为安全的隔离级别, 但同时也是性能最差的隔离级别,因为所有的事务在该隔离级别下都需要依次顺序执行,所以,并发度下降,吞吐量上不去,性能自然就下来了。 因为该隔离级别极大的影响系统性能,所以,很少场景会使用它。通常情况下,我们会使用其他隔离级别加上相应的并发锁的机制来控制对数据的访问,这样既保证了系统性能不会损失太大,也能够一定程度上保证数据的一致性。
__________________________________________________________
对于数据库来说,通常都有一个默认的隔离级别,大多数情况下都是Read Committed,只有Hsqldb使用Read UnCommited作为默认隔离级别。 而且,并非所有的数据库都支持这四种隔离级别,比如Oracle只支持Read Committed和Serializable,如果你指定的隔离级别当前数据库不支持的话, 数据库会采用默认的隔离级别代替你指定的隔离级别。EJB,Spring,JDBC等数据访问方式都允许我们为事务指定以上提到的四种隔离级别,但最终事务是否以指定的隔离级别执行,则由底层的数据资源来决定。

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