SpringBoot手动开启事务:DataSourceTransactionManager问题
作者: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 { ... }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。