Spring事务将一系列操作绑定为具有原子性的操作,此篇文章讲基于Spring提供的声明式事务。
Spring的事务与MySQL事务
MySQL的事务我们已经明白,Spring的事务是委派了ORM框架来解决相应的问题,在jdbc中,体现的就是在Mybatis框架中,体现的就是SqlSession的建立到提交。
声明式事务:在方法或是实现类上加上以下注解:
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.SERIALIZABLE, timeout=36000,rollbackFor=Exception.class)
其中一些常用参数:
propagation:配置事务传播行为;(后面详细解读)
isolation:事务隔离级别;
timeout:超时时间;
roolbackFor:导致事务回滚的异常类设置;
readOnly:boolean,是否只读。
事务传播行为
有七种事务传播行为,用来决策当发生事务嵌套时的解决方案。传播行为即Propagation:
REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。
关于事务的传播机制,在博客Spring事务详细解释,满满的都是干货! - 南北雪树的专栏 - CSDN博客中代码已经讲解的很详尽,以下总结内容引自该篇博客:
NESTED和REQUIRED修饰的内部方法都属于外围方法事务,如果外围方法抛出异常,这两种方法的事务都会被回滚。但是REQUIRED是加入外围方法事务,所以和外围事务同属于一个事务,一旦REQUIRED事务抛出异常被回滚,外围方法事务也将被回滚。而NESTED是外围方法的子事务,有单独的保存点,所以NESTED方法抛出异常被回滚,不会影响到外围方法的事务。
NESTED和REQUIRES_NEW都可以做到内部方法事务回滚而不影响外围方法事务。但是因为NESTED是嵌套事务,所以外围方法回滚之后,作为外围方法事务的子事务也会被回滚。而REQUIRES_NEW是通过开启新的事务实现的,内部事务和外围事务是两个事务,外围事务回滚不会影响内部事务。
实现原理
这里将简单介绍一下Spring事务的实现原理,//TODO