Spring事务-事务传播

数据库层面

一般来说,MySQL中事务是不存在嵌套的可能的,因为每一个start transaction命令都会隐式执行一个commit命令,所以几乎无法创造出事务嵌套的可能。但是可以通过save point命令设置回滚点,模拟出嵌套事务的效果。

应用层面

对于应用层面来说,情况会复杂很多,因为编程使用的是方法,嵌套调用是非常常见的现象,应用该如何表现事务的效果就需要归纳出来,供用户使用。

Spring事务

spring声明式事务是通过生成代理类来实现的,使用jdk动态代理有个很明显的特点,就是如果方法发生嵌套,外层方法会被代理增强,但是内层的方法就直接通过this调用,无法被增强。这也会产生一些误会。

写法1

当调用a()时,b()的事务是无法生效的。

public void a(){
    b();
}

@Transactional
public void b(){
}

写法2

这种写法,b如果抛出异常,a()和b()都会回滚的,而且这种情况下b()上面的事务注解是没有作用的,写了和没写是一样。

@Transactional
public void a(){
    some db operate...
    b();
}

@Transactional
public void b(){
    some db operate...
}

Spring事务传播机制

事务传播讨论的是@Transactional注解应该如何工作,一个方法上如果有@Transactional注解,那么他可能是被另一个方法调用的,这种情况下我们就要讨论事务的传播机制,如果他不是被另一个方法调用,那这个方法就谈不上事务传播了,但是如果这个方法调用了其他的方法,那被他调用的那个方法就要考虑事务传播机制了。事务的传播结果无非就是2种:
1、最终所有方法都在一个事务里面,全部互相影响回滚
2、所有方法会在不同的多个事务里面,回滚会隔离

Spring提供的事务传播机制有7种:
1、REQUIRED (Spring默认)
2、SUPPORTS
3、MANDATORY
4、REQUIRES_NEW
5、NOT_SUPPORTED
6、NEVER
7、NESTED

required方式是说,如果当前方法身处事务中,就加入到当前事务,如果没有身处事务中,就开启一个事务。身处事务中的原因可能是调用他的方法已经开启了事务,没有身处事务中的原因就是他是最外层方法,或者调用他的方法没有开启事务。这种传播机制是最符合人的思维方式的,所以Spring也将他设置为默认的传播方式。

supports方式是说,如果当前方法身处事务中,就加入到当前事务,如果没有身处事务中,不要开启事务。他就是一个支持上游的好伙伴,完全靠向上游,上游有事务,他就有,上游没有,他就没有,所以supports很贴切。

mandatory方式是说,如果当前方法身处事务中,就加入到当前事务,如果当前没有身处事务中,就抛出异常。很强势的一种传播方式,mandatory的意思就是强制的,法定的,没事务就不干活了。

requires_new方式是说,新建一个事务b,如果当前身处事务a中,挂起当前事务a。事务a开启后,写入一些未提交的数据,然后挂起事务a,开启事务b,如果此时事务b发生异常,即使异常被catch吃掉,此时事务a和b都会被回滚,如果事务b未异常,写入数据提交,事务b相关数据立马生效且不会被回滚,事务b结束,事务a被唤醒,继续遵循事务特性执行,此时如果事务a异常回滚,事务b将不受影响。

not_supported是说,不开启事务,如果当前身处事务中,挂起当前事务。效果就是当遇到他时,当前事务被挂起,挂起后not_supported写入的数据立马生效且不会被回滚,直到not_supported方法结束,当前事务才被唤醒,此时遵循事务继续执行,有异常就回滚。

never是说,不开启事务,如果调用他的人开启了事务,抛出异常。never就是拒绝事务的意思。和上面mandatory正好相反。

nested是说,如果当前身处事务a中,不挂起当前事务a,而是开启一个嵌套事务b(同一个事务id),如果b执行过程中异常,当然异常不能抛到a中,此时只回滚b的数据,a的事务继续执行下去,如果a事务回滚,b也会被回滚。这种功能的实现的原理是savepoint命令,可以回滚到一个指定的位置。

在理解这些传播机制时,我们可以按照顺序想像,开启事务a,插入数据,然后或是挂起事务a新建事务b,或是不挂起事务a新建事务b,继续插入数据,遇到异常,回滚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值