• Spring事务


    1.Spring操作事务方式

    一般有三类事务管理的方法:

    1. 使用JDBC的事务管理: 使用DataSource,从数据源中获取connection,通过con的api进行CRUD,手动的进行commit或者rollback。
    2. spring提供的编程式的事务管理 通过编程代码在业务逻辑时需要时自行实现,粒度更小;
    3. 使用spring的声明式事务处理。 通过注解或XML配置实现;

    2.事务管理器PlatformTransactionManager

    事务管理器PlatformTransactionManager为顶级接口。通用的事务处理流程是由抽象事务管理器AbstractPlatformTransactionManager来提供的,而具体的底层事务处理实现,由PlatformTransactionManager的具体实现类来实现,如DataSourceTransactionManager 、JtaTransactionManager和 HibernateTransactionManager等。

    3.JDBC的事务管理

    Connection connection = dataSource.getConnection();
    try {
         connection.setAutoCommit(false);
         appointmentService.createAppointment(appt);
         connection.commit();
    }catch (Exception x){
         try {
             connection.rollback();
         }catch (Exception e){
         }
    }finally {
         try {
             connection.close();
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.编程式事务
    依赖:

    <!--mybatis-spring-boot-starter依赖包中包含了spring-boot-starter-jdbc的依赖,spring-boot-starter-jdbc中包含
    DataSourceTransactionManager事务管理器以及自动注入配置类DataSourceTransactionManagerAutoConfiguration-->
    <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.2.0</version>
     </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用事务模板类 TransactionTemplate

    @Autowired
    private TransactionTemplate transactionTemplate;
    
    @Override
    public void create(){
    	//
       transactionTemplate.execute(new TransactionCallbackWithoutResult() {
           @Override
           protected void doInTransactionWithoutResult(TransactionStatus status) {
                orderItemsService.saveBatch(corderItems);
                procedureService.costFlowApprove(costFlowApproval);
           }
       });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.声明式事务
    5.1 开启事务两种方法:
    5.1 .1 启动类使用注解@EnableTransactionManagement

    会自动注入PlatformTransactionManager接口的实现类。

    5.1 .2 Bean注入使用事务管理器

    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource){
    	return new DataSourceTransactionManager(dataSource);
    }
    
    • 1
    • 2
    • 3
    • 4

    注解@Bean 将被优先加载,框架不会重新实例化其他的 PlatformTransactionManager 实现类。
    5.2 设置多个事务管理器

    @Bean(name = "transactionManager1")
    public PlatformTransactionManager transactionManager(@Qualifier("dataSource1") DataSource dataSource){
    	return new DataSourceTransactionManager(dataSource);
    }
    @Bean(name = "transactionManager2")
    public PlatformTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource){
    	return new DataSourceTransactionManager(dataSource);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用value/transactionManager 具体指定使用哪个事务管理器

    @Transactional(value=""transactionManager1")")
    
    • 1

    假如存在多个PlatformTransactionManager实例,并且没有实现接口TransactionManagementConfigurer指定默认值。
    使用注解@Transactional时,就必须要用value指定使用那个事务。如果不指定,会抛出异常。
    如果系统需要提供默认事务管理,需要实现接口 TransactionManagementConfigurer 指定。
    如果在业务中必须要明确指定@Transactional的value值,为了避免不必要的问题。不建议实现接口TransactionManagementConfigurer,这样会明确抛出异常,就不会忘记主动指定。

    5.3 @Transactional注解相关属性
    value和transactionManager属性

    配置文件中有多个事务管理器 , 可以用该属性指定选择哪个事务管理器。

    propagation属性事务的传播行为 默认为:Propagation.REQUIRED
    共有七个传播行为:

    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
    当前没有事务,就新建一个事务。如果已经存在一个事务中,加入到这个事务中
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
    当前存在事务,加入该事务。如果当前不存在事务,就以非事务方式执行。
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
    使用当前的事务,如果当前没有事务,抛出异常。
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
    新建事务,如果当前存在事务,把当前事务挂起(相当于停止)。
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
    以非事务方式执行,如果当前存在事务,就把当前事务挂起。
    NEVER(TransactionDefinition.PROPAGATION_NEVER),
    以非事务方式执行,如果当前存在事务,则抛出异常。
    NESTED(TransactionDefinition.PROPAGATION_NESTED);
    支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。与PROPAGATION_REQUIRED类似的操作。

    isolation属性 事务的隔离级别,默认值为 DEFAULT

    DEFAULT(TransactionDefinition.ISOLATION_DEFAULT) 根据数据库默认的隔离级别配置
    数据库不同配置不同。mysql默认为可重复读REPEATABLE_READ
    READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED) 读取未提交
    READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED) 读取已提交
    REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ) 可重复读
    SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE) 串行化

    timeout属性

    设置事务的超时秒数,默认值为-1表示永不超时。如果超过该时间限制但事务还没有完成,则自动回滚事务。

    readOnly属性

    设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
    @Transactional(readOnly=true)

    rollbackFor属性

    设置需要进行回滚的异常类型,当方法中抛出指定异常类型中的异常时,事务回滚。
    指定一个类:@Transactional(rollbackFor=RuntimeException.class)
    指定多个类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

    rollbackForClassName属性

    设置需要进行回滚的异常类名称,当方法中抛出指定异常类名称中的异常时,事务回滚。
    指定一个名称:@Transactional(rollbackForClassName=“RuntimeException”)
    指定多个名称:@Transactional(rollbackForClassName={“RuntimeException”,“Exception”})

    noRollbackFor属性

    设置不需要进行回滚的异常类型,当方法中抛出指定异常类型中的异常时,不进行事务回滚。
    指定一个名称:@Transactional(noRollbackFor=RuntimeException.class)
    指定多个名称:@Transactional(noRollbackFor={RuntimeException.class,Exception.class})

    noRollbackForClassName属性

    设置不需要进行回滚的异常类名称,当方法中抛出指定异常名称中的异常时,不进行事务回滚。
    指定一个名称:@Transactional(noRollbackForClassName=“RuntimeException”)
    指定多个名称:@Transactional(noRollbackForClassName={“RuntimeException”,“Exception”})

    5.4 使用@Transactional注意
    5.4.1 @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能。
    5.4.2 有事务方法,遇到RuntiomeException时会回滚,遇到受检查的异常不会回滚,要想所有异常都回滚,要加上@Transactional(rollbackFor = Exception.class)

  • 相关阅读:
    ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式
    EasyRL-第二章
    2023年下半年架构案例真题及答案
    jar服务导致cpu飙升问题-带解决方法
    jsp页面编码解析规则
    用巴特沃斯滤波器对原始信号进行滤波
    STK与MATLAB互联——仿真导航卫星与地面用户间距离和仰角参数
    unity面试题(基础篇)
    2022数模国赛C题思路解析(回顾,可供后面的比赛训练用)
    Python将10G的文件拆分成多个小文件
  • 原文地址:https://blog.csdn.net/m0_50176078/article/details/128020825