Spring事务管理


Spring抽象了事务管理策略模型,为处理不同实现机制的事务提供了统一的编程模型。

核心模型

«interface» TransactionManager «interface» PlatformTransactionManager «interface» ReactiveTransactionManager «interface» TransactionStatus «interface» ReactiveTransaction «interface» TransactionDefinition getTransaction getReactiveTransaction
  • Spring事务管理抽象分为命令时事务管理模型(PlatformTransactionManager)和响应式事务管理模型(ReactiveTransactionManager),PlatformTransactionManager为命令式应用事务抽象,ReactiveTransactionManager为响应式应用(Reactive Application)事务抽象
  • TransactionDefinition 定义了事务的传播方式、隔离级别、超时、回滚、只读事务
  • TransactionStatus(ReactiveTransaction) 定义了事务的执行以及事务的状态

事务管理方式分类

声明式事务管理

声明式事务管理主要通过切面代理和metadata(注解和xml配置)配置来实现,TransactionInterceptor根据当前的编程语言模型( imperative 、 reactive)来选择合适的事务策略模型。事务的核心注解**@Transactional**在命令式编程模型中,只能处理当前线程范围的事务,不能把事务传递到新线程,在响应式编程模型中,也只能处理当前contenxt(Reactor context)的事务

注解驱动事务配置(TransactionManager)

mode
  • proxy 使用spring aop framwork来代理目标对象的方法调用,目标对象的方法只能是公共方法
  • aspectj 采用spring aspectj 事务切面,通过修改字节码方式织入事务,可以应用于任何类型的方法调用
proxy-target-class

该属性是在mode为proxy配置时,指定事务注解是基于具体类的代理还是基于接口代理

注意事项
  • Spring自身框架中,@Transactional仅支持公共方法,如果需要在非公共方法上使用事务注解,使用aspectj模式
  • 由于java中注解是不能从接口继承的,所以,最好把注解使用到具体类或具体类的方法上
  • 代理模式下,方法的调用会被代理拦截,因此,同类中的方法调用即使被调用方法有事务注解,也不会使用事务
  • 方法事务设置优先于类事务设置
  • Spring默认只对未检查的RuntimeException进行回滚,如要Exception及子类进行回滚,需要进行配置

事务注解配置(@Transactional)

Spring事务注解的关键配置包括传播类型(propagation)隔离级别(isolation)读写(read-only)超时(timeout)回滚(rollback-for/no-rollback-for)。事务分为逻辑事务和物理事务,不同的传播类型将影响内部事务设置(isolation、read-only、timeout)

事务传播类型
PROPAGATION_REQUIRED(一个物理事务,多个逻辑事务)
  • 强制开启一个物理事务, 内部每个方法将开启一个逻辑事务,每个逻辑事务可以独立的设置rollback-only status,由于只有一个物理事务,内部事务的rollbakc-only设置将影响外部事务的提交
  • 如果内部事务设置了rollback-only,但是外部事务又没有决定回滚自己,将会出现UnexpectedRollbackException异常
public class A{
	 @Transactional
    public void updataA(Integer id){
            return jdbcTemplate.update("update store set num=num-1 where bookid=?",id);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updateB(Integer id,Double price) throws Exception {
        int update = jdbcTemplate.update("update book set price=price+? where id=?", price, id);
        throw  new Exception("test");
       
    }
}

public class B{
	private A a;
    @Transactional
    public void  update() throws  Throwable{
        a.updateA(1);
        //int a=1/0;
        a.updateB(1,50.0);
    }
}

  • 默认情况下内部事务的隔离级别、timeout、 read-only设置将被忽略,如果内部事务需要单独设置,需要在事务管理(Transaction Manager)的配置中开启validateExistingTransactions
PROPAGATION_REQUIRES_NEW(多个物理事务)

每个使用了@Transactional注解都使用独立的物理事务

PROPAGATION_NESTED(一个物理事务,多个savepoint)

一个物理事务,每个内部事务有一个savepoint,因此,内部事务的回滚,不影整个事务,同时由于savepoint 映射为jdbc的savepoint,因此只适用于jdbc 事务类型

编程事务

  • 命令式语言使用TransactionTemplate ,响应式语言使用 TransactionalOperator
  • 直接实现TransactionManager
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值