SpringBoot手动开启事务:DataSourceTransactionManager问题

 更新时间:2023年07月06日 16:52:58   作者:cying2029  
这篇文章主要介绍了SpringBoot手动开启事务:DataSourceTransactionManager问题,具有很好的价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

DataSourceTransactionManager

添加事务:

  • 传统JDBC事务管理,使用DataSource从数据源中获取connection
  • 通过api进行CRUD,之后手动commit、rollback。
  • 应用spring提供的编程式的事务管理
  • 使用spring的声明式事务处理

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

SpringBoot中手动开启事务常用代码

@Controller
public class TransactionDemo {
    @Autowired
    private DataSourceTransactionManager transactionManager;
    @RequestMapping("test")
    public void test(){
        //可做单例
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehaviorName("PROPAGATION_REQUIRED");
        TransactionStatus transaction = transactionManager.getTransaction(definition);
//        TransactionStatus transaction = transactionManager.getTransaction(TransactionDefinition.withDefaults());
        try {
            //do something
            transactionManager.commit(transaction);
        }catch (Exception e){
            //do error
            transactionManager.rollback(transaction);
        }
    }
}

DataSourceTransactionManager总结

1.Spring框架配置事务

1.1基于schema的自动代理

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!--对数据源进行代理,使数据源具有感知事务上下文的能力,当某些场景下显示获取数据库连接时,保证获取到的连接是绑定了当前事务的连接(和通过DataSourceUtils.getConnection()获取连接的效果一致)-->
    <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"
        p:targetDataSource-ref="dataSource"/>
    <!--声明式事务管理器-->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSourceProxy"/>
    <!--基于schema的自动代理-->
    <aop:config>
        <!--切点 匹配com.fxy子包下的所有方法-->
        <aop:pointcut id="serviceMethod"
                      expression="execution(* com.fxy..*.*.service..*.*(..))"/>
        <!--切面-->
        <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
    </aop:config>
    <!--增强 新增变更删除方法 遇到检查型异常和非检查型异常均回滚-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="list*" read-only="true"/>
            <tx:method name="save*" rollback-for="Exception"/>
            <tx:method name="update*" rollback-for="Exception"/>
            <tx:method name="delete*" rollback-for="Exception"/>
            <tx:method name="*" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>
</beans>

查看tx:advice标签,可以追踪到TransactionInterceptor类,其实现了MethodInterceptor接口,会在目标方法前后实施增强(即使用txManager,在方法执行前关闭Connection对象自动提交,方法执行完成后执行Connection对象提交方法,异常时执行Connection对象回滚方法)。

1.2使用@transactional注解

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!--对数据源进行代理,使数据源具有感知事务上下文的能力,当某些场景下显示获取数据库连接时,保证获取到的连接是绑定了当前事务的连接(和通过DataSourceUtils.getConnection()获取连接的效果一致)-->
    <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"
        p:targetDataSource-ref="dataSource"/>
    <!--声明式事务管理器-->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        p:dataSource-ref="dataSourceProxy"/>
    <!--对使用transactional注解的bean进行加工,织入事务管理切面 -->
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>

2.SpringBoot框架配置事务

2.1@Transactional注解

2.1.1SpringBoot自动装配事务管理器

package org.springframework.boot.autoconfigure.jdbc;
import javax.sql.DataSource;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.support.JdbcTransactionManager;
import org.springframework.transaction.TransactionManager;
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({JdbcTemplate.class, TransactionManager.class})
@AutoConfigureOrder(2147483647)
@EnableConfigurationProperties({DataSourceProperties.class})
public class DataSourceTransactionManagerAutoConfiguration {
    public DataSourceTransactionManagerAutoConfiguration() {
    }
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnSingleCandidate(DataSource.class)
    static class JdbcTransactionManagerConfiguration {
        JdbcTransactionManagerConfiguration() {
        }
        @Bean
        @ConditionalOnMissingBean({TransactionManager.class})
        DataSourceTransactionManager transactionManager(Environment environment, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
            DataSourceTransactionManager transactionManager = this.createTransactionManager(environment, dataSource);
            transactionManagerCustomizers.ifAvailable((customizers) -> {
                customizers.customize(transactionManager);
            });
            return transactionManager;
        }
        private DataSourceTransactionManager createTransactionManager(Environment environment, DataSource dataSource) {
            return (DataSourceTransactionManager)((Boolean)environment.getProperty("spring.dao.exceptiontranslation.enabled", Boolean.class, Boolean.TRUE) ? new JdbcTransactionManager(dataSource) : new DataSourceTransactionManager(dataSource));
        }
    }
}

2.2SpringBoot多数据源配置

2.2.1给数据源指定事务管理器

   @Bean("db1TxManager")
   public DataSourceTransactionManager db1TxManager(@Qualifier("db1DataSource") DataSource dataSource ){
       DataSourceTransactionManager txManager = new DataSourceTransactionManager();
       txManager.setDataSource(dataSource);
       return txManager;
   }
   @Bean("db2TxManager")
   public DataSourceTransactionManager db2TxManager(@Qualifier("db2DataSource") DataSource dataSource ){
       DataSourceTransactionManager txManager = new DataSourceTransactionManager();
       txManager.setDataSource(dataSource);
       return txManager;
   }

2.2.2注解上指定事务管理器

@Service("baseService1")
@Transactional("db1TxManager")
public class BaseService1 {
...
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 深入理解Java8新特性之Lambda表达式的基本语法和自定义函数式接口

    深入理解Java8新特性之Lambda表达式的基本语法和自定义函数式接口

    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑
    2021-11-11
  • java的io操作(将字符串写入到txt文件中)

    java的io操作(将字符串写入到txt文件中)

    这篇文章主要介绍了java的io操作示例,将字符串写入到txt文件中,需要的朋友可以参考下
    2014-04-04
  • Java Web 登录页面的实现代码实例

    Java Web 登录页面的实现代码实例

    这篇文章主要介绍了Java Web 登录页面的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Java 实现跨平台的操作方式

    Java 实现跨平台的操作方式

    这篇文章主要介绍了Java 实现跨平台的操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • JAVA使用POI获取Excel的列数与行数

    JAVA使用POI获取Excel的列数与行数

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 下面这篇文章给大家介绍了JAVA使用POI获取Excel列数和行数的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • 详细分析JVM类加载机制

    详细分析JVM类加载机制

    JVM将class文件字节码文件加载到内存中, 并将这些静态数据转换成方法区中的运行时数据结构,在堆(并不一定在堆中,HotSpot在方法区中)中生成一个代表这个类的java.lang.Class 对象,作为方法区类数据的访问入口,接下来将详细讲解JVM类加载机制
    2022-04-04
  • SpringCloud Feign远程调用与自定义配置详解

    SpringCloud Feign远程调用与自定义配置详解

    Feign是Netflix公司开发的一个声明式的REST调用客户端; Ribbon负载均衡、 Hystrⅸ服务熔断是我们Spring Cloud中进行微服务开发非常基础的组件,在使用的过程中我们也发现它们一般都是同时出现的,而且配置也都非常相似
    2022-11-11
  • Java 并发编程之线程挂起、恢复与终止

    Java 并发编程之线程挂起、恢复与终止

    这篇文章主要介绍了Java 并发编程之线程挂起、恢复与终止的相关资料,需要的朋友可以参考下
    2017-05-05
  • BeanFactory和FactoryBean的区别示例详解

    BeanFactory和FactoryBean的区别示例详解

    这篇文章主要为大家介绍了BeanFactory和FactoryBean的区别示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • SpringBoot自定义注解开发指南

    SpringBoot自定义注解开发指南

    在开发SpringBoot程序的过程中,有可能与其他业务系统进行对接开发,获取封装公共的API接口等等,下面这篇文章主要给大家介绍了关于SpringBoot自定义注解的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论