问题:
CobarClient(https://github.com/alibaba/cobarclient 下面简称CC)在Spring2.5下的配置事务管理器
<bean id="transactionManager"
class="com.alibaba.cobar.client.transaction.MultipleDataSourcesTransactionManager">
<property name="cobarDataSourceService" ref="dataSources" />
<property name="globalRollbackOnParticipationFailure" value="true" />
</bean>
但是在Spring3.x下面这样配置,在启动事务的时候,会有错误
java.lang.IllegalStateException: Cannot activate transaction synchronization - already active
at org.springframework.transaction.support.TransactionSynchronizationManager.initSynchronization(TransactionSynchronizationManager.java:270)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.prepareSynchronization(AbstractPlatformTransactionManager.java:537)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy10.createOffersInBatch(Unknown Source)
at com.alibaba.cobar.client.transaction.MultipleDataSourcesTransactionManagerTest.testOfferCreationOnMultipleShardsWithNormallyOfferService(MultipleDataSourcesTransactionManagerTest.java:94)
检查原因:
启动事务的时候,TransactionManager会调用getTransaction方法初始化事务,这里面会调用子类的doBegin方法
而MultipleDataSourcesTransactionManager(CC实现的子类)的doBegin方法中将调用各个实际数据源DataSourceTransactionManager的getTransaction方法,从而开启各个数据源的事务
List<DefaultTransactionStatus> list = (List<DefaultTransactionStatus>) transactionObject;
for (PlatformTransactionManager transactionManager : transactionManagers) {
DefaultTransactionStatus element = (DefaultTransactionStatus) transactionManager
.getTransaction(transactionDefinition);
list.add(element);
}
ps:其实最好做法是调用各个实际数据源的doBegin方法,但是因为这个方法是protected的,无法在外部调用,只能退而求其次,调用getTransacation方法。
但是在新版spring下面,MultipleDataSourcesTransactionManager的抽象类AbstractPlatformTransactionManager进行了重写
getTransaction方法内部在调用doBegin之后又调用了prepareSynchronization方法
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
这个方法会调用initSynchronization初始化一个ThreadLocal变量synchronizations
在初始化之前会检查该变量是否已经初始化了,如果出现就报错。
而CC的doBegin是调用了getTransaction,所以该变量会初始化多次,所以导致无法通过检查。
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?
definition.getIsolationLevel() : null);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
TransactionSynchronizationManager.initSynchronization();
}
}
但是如果我们把transactionManager 的transactionSynchronization设置为SYNCHRONIZATION_NEVER,就会避免initSynchronization重复初始化问题,
因为MultipleDataSourcesTransactionManager的isNewSynchronization属性为false,initSynchronization就不会执行。
Spring3.x中设置如下:
<bean id="transactionManager" class="com.alibaba.cobar.client.transaction.MultipleDataSourcesTransactionManager">
<property name="cobarDataSourceService" ref="dataSources" />
<property name="transactionSynchronization" value="2" />
</bean>
TransactionSynchronization的含义:
下面摘自网上的描述
TransactionSynchronization是可以注册到事务处理过程中的回调接口。它就像是事务处理的事件监听器,当事务处理的某些规定时点发生时,会调用TransactionSynchronization上的一些方法来执行相应的回调逻辑,如在事务完成后清理相应的系统资源等操作。Spring事务抽象框架所定义的TransactionSynchronization类似于JTA规范的javax.transaction.Synchronization,但比JTA的Synchronization提供了更多的回调方法,允许我们对事务的处理添加更多的回调逻辑。
看起来TransactionSynchronization应该是类似AOP的一种对事务事件的回调,不过我没有用过。
可能导致的问题:
个人分析-不会,因为我们屏蔽的只是CC的MultipleDataSourcesTransactionManager的transactionSynchronization属性,而实际的数据源事务管理器的transactionSynchronization仍然是默认的SYNCHRONIZATION_ALWAYS。
总结一下,可以这样认为,我们在CC中不支持transactionSynchronization特性。
其实我们对MultipleDataSourcesTransactionManager设置的属性都没有应用到的数据源事务管理器DataSourcesTransactionManager上
分享到:
相关推荐
Spring 3.x 注解应用详解 Spring 3.x 框架引入了依赖注入的注解,改变了传统的 XML 配置方式,提供了一种更加灵活和方便的依赖配置方式。下面对 Spring 3.x 的注解应用进行详细的介绍。 一、属性装配 在 Spring ...
Spring 3.x 的主要改进包括:对 Java 5 的全面支持、更强大的表达式语言、改进的数据访问能力、REST 支持、MVC 改进等。 #### 二、基于 Annotation 的 Cache 服务 Spring 3.x 引入了一个全新的缓存机制,该机制基于...
Spring 3.x是Spring框架的一个重要版本,它提供了丰富的功能更新和性能优化,为Java开发者带来了更强大、灵活的依赖注入(DI)和面向切面编程(AOP)支持。 首先,让我们深入了解Spring的核心概念和特性: 1. **...
1. **AOP(面向切面编程)**:Spring 3.x在AOP方面进行了优化,使得切面定义更加简洁,支持更多的通知类型,并且增强了对注解的支持,使得切面编程更为直观。 2. **MVC(模型-视图-控制器)**:Spring 3.x的Web MVC...
1. 支持Java 8:Spring 4.x全面支持Java 8,包括Lambda表达式、日期和时间API等,使得代码更加简洁和易读。 2. WebSocket支持:Spring 4.x引入了WebSocket支持,通过STOMP(Simple Text Oriented Messaging ...
《第5本书 spring3.x》是一本深入探讨Spring 3.x版本的IT技术书籍,主要聚焦于Spring框架的核心特性和实战应用。Spring是Java领域中最受欢迎的轻量级框架之一,它以其依赖注入(Dependency Injection)和面向切面...
1.精通Spring 4.x 企业应用开发实战精通Spring 4.x 企业应用开发实战精通Spring 4.x 企业应用开发实战精通Spring 4.x 企业应用开发实战精通Spring 4.x 企业应用开发实战精通Spring 4.x 企业应用开发实战精通Spring 4...
3. **RESTful支持**:Spring 3.x开始支持RESTful Web服务,通过`@RequestMapping`注解和其他相关注解,可以轻松创建符合REST原则的接口。 4. **消息支持**:Spring 3.x增加了对JMS(Java Message Service)的支持,...
Spring3.x企业应用开发实战(包括源码)绝对完整版 因未见太大,分8个小块(其他部分在本人资料里面查找),只有前4个每个收1分,后面4个免费下载,共4分,绝对完整,包含所有章节,不完整浏览分享
3. **Bean管理**:Spring管理Bean的生命周期和状态,可以创建单例或多例Bean,支持Bean的初始化和销毁方法,以及Bean之间的协作。 4. **数据访问集成**:Spring4.x支持多种数据访问技术,包括JDBC、ORM(如...
《Spring 3.x企业应用开发实战》是一本深入讲解Spring框架在企业级应用程序开发中的实践指南。这本书专注于Spring 3.x版本,该版本是Spring框架发展史上的一个重要里程碑,引入了许多新特性和改进,旨在提升开发效率...
8. **Spring Test**:Spring3.X提供了丰富的测试支持,包括`@RunWith(SpringJUnit4ClassRunner.class)`和`@ContextConfiguration`等注解,简化了单元测试和集成测试的编写。 9. **Asynchronous Processing**:...
Spring 4.x版本是其发展过程中的一个重要里程碑,它引入了对Java 8特性的支持,改进了对Web和数据库交互的处理,并提供了更强大的模块化设计。 在Spring 4.x中,依赖注入是其核心设计原则之一,它允许开发者解耦...
安全性方面,Spring Security 4.x.x与Spring 4.x.x紧密集成,提供了全面的身份验证和授权功能,包括OAuth2支持,保护了Web应用和RESTful API的安全。 总的来说,Spring 4.x.x中文文档将涵盖这些关键领域的详细内容...
Spring 3.x+Spring MVC 3.x+MyBatis 3.x 整合代码 该代码仅截止到《Spring 3.x+Spring MVC 3.x+MyBatis 3.x 整合(五)MyBatis 3.2.5 整合》,原文件地址:http://blog.csdn.net/xz2001/article/details/44346355
Spring作为Java领域中最流行的开源框架之一,它的3.x版本为开发者提供了丰富的功能和强大的支持,使得构建复杂的企业级应用变得更为简单。本书结合PDF教程与源码,旨在帮助读者深入理解并熟练掌握Spring 3.x的核心...
Spring 5.x带来了许多性能改进和新特性,如Reactor支持以实现响应式编程,以及对Java 8和Java EE 8的全面兼容。Spring框架的核心是依赖注入(DI),它允许开发者创建松耦合的组件,便于测试和维护。 Hibernate 5.x...
精通Spring 4.x 企业应用开发实战 陈雄华 PDF,清晰而且有标签,目录,非常好,谢谢分享。精通Spring 4.x 企业应用开发实战 陈雄华 PDF,清晰而且有标签,目录,非常好,谢谢分享。
8. **测试支持**:Spring提供了丰富的测试支持,包括单元测试和集成测试。学习如何使用Mockito、Spring Test和JUnit进行测试是非常重要的。 9. **Spring Batch**:对于批量处理任务,Spring Batch提供了一个全面的...
6. REST支持:Spring 3.x增加了对RESTful Web服务的全面支持,允许开发者通过注解轻松地将控制器映射到HTTP请求,并支持多种内容协商机制。 7. 测试支持:Spring提供了一套完整的测试支持库,包括模拟对象、测试上...