Spring事务

Spring事务

spring管理事务方法

  1. 编程式事务:代码中通过TransactionTemplate或者TransactionManager手动管理事务
  2. 声明式事务:直接使用注解@Transaction(最常用)

Spring事务中有哪几种事务传播行为

什么是事务传播行为:解决各个业务层方法互相调用的事务问题

当事务方法被另一个事务方法调用的时候,接下来事务该怎么走?

  1. TransactionDefinition.PROPAGATION_REQUIRED:这是使用最多的一个事务传播行为,我们平时使用的@Transaction注解默认使用的就是这个事务传播行为。如果之前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  2. xxxxx没必要了解那么多

事务隔离级别

为了方便事务传播行为这一块,Spring相应的定义了一个枚举类:Isolation

  • TransactionDefinition.ISOLATION_DEFAult :使用后端数据库默认的隔离级别,MySQL 默认采用的 REPEATABLE_READ 隔离级别 Oracle 默认采用的 READ_COMMITTED 隔离级别.
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED :最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • TransactionDefinition.ISOLATION_READ_COMMITTED : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • TransactionDefinition.ISOLATION_REPEATABLE_READ : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • TransactionDefinition.ISOLATION_SERIALIZABLE : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

@Transaction(rollbackFor=Exception.class)了解

  • Exception分为运行时异常(runtimeException)和非运行时异常.

  • 事务管理是至关重要的,即使出现异常情况,也要保证数据的一致性

  • 如果不使用@Transaction(rollback)的话:事务只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class`,可以让事物在遇到非运行时异常时也回滚。

  • 当 `@Transactional 注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。

最常用的@Transaction详解

@Transaction 是 Spring 提供用来控制事务回滚/提交的一个注解,让我们从编程式注解转换到声明式注解。

  • 当标注在类上的时候:表示给该类所有的 public 方法添加上 @Transaction 注解
  • 当标注在接口上的时候:Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。像 CGLib 动态代理采用继承的方式将会导致 @Transactional 注解失效
  • 当标注在方法上的时候:事务的作用域就只在该方法上生效,并且如果类及方法上都配置 @Transaction 注解时,方法的注解会覆盖类上的注解

实例理解:

下面这个实例是用于区别事务传播行为:require和Nest的,但是也可以用来理解事务的作用

Require::如果当前存在事务,则加入该事务;如果当前不存在事务,则创建一个新的事务;

NESTED:如果当前存在事务,则在该事务内嵌套事务运行;

如果当前不存在事务,则创建一个新的事务;

@Service
public class ServiceA{
    @Autowired
    private ServiceB serviceB;
@Transaction
public void A(){
    try{
        serviceB.B();
    }catch(Exception e){
        e.printStackTrace();
    } 
    //伪代码,执行数据库修改操作
}
@Service
public class ServiceB{
@Transaction(propagation = Propagation.REQUIRED)
public void B(){
    //伪代码,执行数据库修改操作
}

}
如上存在 ServiceA、ServiceB 两个类和A、B两个方法(这里指的异常都是 RuntimeException 异常或其子类)

情况一:A方法中出现了异常,结果A、B方法修改操作都会被回滚
情况二:B方法中出现了异常,结果A、B方法修改操作都会被回滚

@Service
public class ServiceB{
@Transaction(propagation = Propagation.NESTED)
public void B(){
    //伪代码,执行数据库修改操作
}

}
接下来将B方法的 propagation 修改为 NESTED 事务传播机制

情况一:A方法中出现了异常,结果A、B方法修改操作都会被回滚
情况二:B方法中出现了异常,结果B方法修改操作被回滚,A方法修改操作提交

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值