java事务传播特性共分为7种,默认的是REQUIRED
REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);
【REQUIRED】
service1:事务传播机制:REQUIRED
service2:事务传播机制:REQUIRED
REQUIRED:支持事务,没有事务时创建新的事务,如果存在事务则直接加入该事务执行
method1执行时没有事务,则会新建事务Tx1,在method1中调用method2时,发现已经存在事务,则会加入事务执行,最后执行commit
【SUPPORTS】
如果其他bean调用这个方法时,其他bean声明了事务,则就用这个事务,如果没有声明事务,那就不用事务
service1:事务传播机制:REQUIRED
service2:事务传播机制:SUPPORTS
method1执行时没有事务,则会新建事务Tx1,method2执行时检查到存在事务,则在事务中进行执行,然后进行commit
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:SUPPORTS
method1执行不会创建事务,method2也不会创建事务
SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务
【MANDATORY】
必须在一个已有的事务中执行,否则报错
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:MANDATORY
method1不会创建事务执行,method2执行时检查当前没有事务,则会抛出异常不会执行,method1已经在数据库层面执行成功并完成commit,所以抛出的异常不影响method1的执行结果
MANDATORY必须在已有事务下被调用,否则报错
【REQUIRES_NEW】
REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务
service1:事务传播机制:REQUIRED,
service2:事务传播机制:REQUIRES_NEW
执行method1时会创建新的事务Tx1,执行method2时会先将Tx1挂起,然后创建新的事务Tx2,执行完后Tx2进行commit,然后将Tx1解除挂起,Tx1进行commit
REQUIRES_NEW为当前方法创建一个新的事务,并且当前事务先提交,然后再提交老的事务
新的事务提交成功之后,老的事务提交失败时新的事务的sql不会回滚
新的事务提交失败回滚,老的事务是否会进行回滚?应该会的
【NOT_SUPPORTED】
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:REQUIRED
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起
method1执行不会创建事务,执行method2时会创建新的事务,执行sql之后会进行commit
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:NOT_SUPPORTED
两个方法都不会创建事务执行
NOT_SUPPORTED相当于没有Spring事务,每条执行语句单独执行,单独提交
【NEVER】
须在一个没有事务中执行,否则报错
service1:事务传播机制:REQUIRED
service2:事务传播机制:NEVER
method1执行时没有事务,则会新建事务Tx1,method2执行时检查到存在事务,则会进行报错抛出异常,method1由于还没有提交事务,则会进行回滚
【NESTED】
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作
service1:事务传播机制:REQUIRED
service2:事务传播机制:NESTED
method1执行时没有事务,则会新建事务Tx1,执行sql后不会提交,method2创建一个NESTED嵌套事务执行sql,然后一起提交
method1方法创建一个事务,则再调用method2方法时,直接在该事务的基础上创建一个嵌套事务,本质上还是同一个事务,做一次提交;
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:NESTED
method1执行不会创建事务,sql执行在数据库commit,method2会创建一个事务执行sql后commit
method1方法不创建事务,则调用method2方法时,直接创建一个新的事务,单独提交
用法:
@Transactional(propagation = Propagation.REQUIRED)
public void transcationTest(){
.....
}
用注解的方式添加事务时,类内部调用带有注解的方法,事务不生效。注解的事务使用aop切入上的。
可以注入当前类,调用类下的方法。