spring事务的隔离级别和传播方式

 

传播行为

                        

事务传播行为类型sql

                        
                        

说明数据库

                        
                        

PROPAGATION_REQUIRED并发

                        
                        

若是当前没有事务,就新建一个事务,若是已经存在一个事务中,加入到这个事务中。这是最多见的选择。性能

                        
                        

PROPAGATION_SUPPORTSspa

                        
                        

支持当前事务,若是当前没有事务,就以非事务方式执行。排序

                        
                        

PROPAGATION_MANDATORY事务

                        
                        

使用当前的事务,若是当前没有事务,就抛出异常。ci

                        
                        

PROPAGATION_REQUIRES_NEWit

                        
                        

新建事务,若是当前存在事务,把当前事务挂起。io

                        
                        

PROPAGATION_NOT_SUPPORTED

                        
                        

以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。

                        
                        

PROPAGATION_NEVER

                        
                        

以非事务方式执行,若是当前存在事务,则抛出异常。

                        
                        

PROPAGATION_NESTED

                        
                        

若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与PROPAGATION_REQUIRED相似的操做。

                        


PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被彻底 commited 或 rolled back 而不依赖于外部事务, 它拥有本身的隔离范围, 本身的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行. 

    另外一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务,  它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,  它将取得一个 savepoint. 若是这个嵌套事务失败, 咱们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交. 

    因而可知, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 彻底是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 若是外部事务 commit, 潜套事务也会被 commit, 这个规则一样适用于 roll back.

隔离级别

跟sql中的隔离级别是同样的,只是多了一种默认级别(对应数据库的默认级别)

 

SQL标准定义了4中隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级通常支持更高的并发处理,并拥有更低的系统开销。

Read Uncommitted(读取未提交内容) 

在该隔离级别,全部事务均可以看到其余未提交事务的执行结果。本隔离级别不多用于实际应用,由于它的性能也不比其余级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。  

Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它知足了隔离的简单定义:一个事务只能看见已经提交事务所作的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),由于同一事务的其余实例在该实例处理其间可能会有新的commit,因此同一select可能返回不一样结果。 

Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到一样的数据行。 不过理论上,这会致使另外一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时, 另外一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。 InnoDB和Falcon存储引擎经过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 

Serializable(可串行化)  

这是最高的隔离级别,它经过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每一个读的数据行上加上共享锁。在这个级别,可能致使大量的超时现象和锁竞争。

 

锁与隔离级别的关系

隔离级别是根据锁的不一样组合方式实现的,锁分行级锁,表级锁,页级锁还有另外一个纬度分为写锁和读锁。

其实乐观锁是在应用中实现的根本没有在数据库中加锁。

相关文章
相关标签/搜索