`
cenwenchu
  • 浏览: 161649 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring事务管理的失效和Proxy类型的DataSource

阅读更多

Spring事务管理的失效和Proxy类型的DataSource

<o:p> </o:p>

       在服务框架中,我们由于需要将DataSource作为第三方服务暴露给其他模块(此处是十分不推荐的,因为如果作为服务那么首先就要求该服务没有状态),因此就采用JdkProxy来实现虚拟DataSource暴露给其他模块以及第三方。

<o:p> </o:p>

环境:

       采用ASF(基于SCA服务框架的应用服务框架)暴露DataSource作为第三方服务,其他模块的Ibatis SqlMapClientSpringTransactionManager都注入了这个Proxy类型的DataSource

<o:p> </o:p>

问题:

       发现Spring注入DataSourceProxy以后,使用是正常的,但是事务却失效了,JDBC事务失效。

<o:p> </o:p>

分析:

       跟踪察看了spring的代码,发现原来spring中的TransactionManager在事务启动和结束的时候,都是首先将DataSourceConnectionHolderThreadLocal中保存,然后在事务过程中获取的都是保存过的Connection,出错也是会滚该Connection<o:p></o:p>

       但是由于当前使用的是ProxyDataSource,虽然每一次Call的时候都是调用同一个DataSource,但是在事务开始的时候,获取的是注入到TransactionManager中的DataSource Proxy,在事务进行过程中,使用的是新的Proxy,在ThreadLocalMap中存在了两份DataSource Proxy的信息也就是有两份ConnectionHolder,这导致在事务开始的时候,将connectionautocommitfalse,然后放入到第一个DataSource Proxy作为KeyEntry中,无法被后面事务进行所获取,事务进行的时候默认将会通过DataSource产生一个新的Connection同时autocommit失效,因此产生了事务失效的问题。<o:p></o:p>

<o:p> </o:p>

Spring的事务处理流程图:<o:p></o:p>

<v:shapetype o:spt="75" coordsize="21600,21600" filled="f" stroked="f" id="_x0000_t75" path=" m@4@5 l@4@11@9@11@9@5 xe" o:preferrelative="t"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0 "></v:f><v:f eqn="sum @0 1 0 "></v:f><v:f eqn="sum 0 0 @1 "></v:f><v:f eqn="prod @2 1 2 "></v:f><v:f eqn="prod @3 21600 pixelWidth "></v:f><v:f eqn="prod @3 21600 pixelHeight "></v:f><v:f eqn="sum @0 0 1 "></v:f><v:f eqn="prod @6 1 2 "></v:f><v:f eqn="prod @7 21600 pixelWidth "></v:f><v:f eqn="sum @8 21600 0 "></v:f><v:f eqn="prod @7 21600 pixelHeight "></v:f><v:f eqn="sum @10 21600 0 "></v:f></v:formulas><v:path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape coordsize="21600,21600" id="_x0000_i1025" type="#_x0000_t75" style="WIDTH: 414.75pt; HEIGHT: 585.75pt"><v:imagedata src="E13197E4.files/image001.emz" o:title=""></v:imagedata></v:shape>

1 Spring 事务处理流程图

<o:p> </o:p>

解决方法:

       其实只需要让Spring TransactionManager能够将DataSource真实实例获得并作为Entry Key保存到ThreadLocal中即可,那么就有两种方式,一种将就是将分开的配置放在一起,那么这里看TransactionManager应该是外部不需要配置的,可以和DataSource配置在一个spring中,那么就不需要用Proxy的方式,另一种不得不用Proxy的方式,例如对于IbatisSqlMapClient。处理方法如下:

<o:p> </o:p>

<v:shape coordsize="21600,21600" id="_x0000_i1026" type="#_x0000_t75" style="WIDTH: 415.5pt; HEIGHT: 288.75pt"><v:imagedata src="E13197E4.files/image003.emz" o:title=""></v:imagedata></v:shape>

2 DataSource 解决方法类图

<o:p> </o:p>

       不再将DataSource作为服务暴露给第三方,而是将内部封装DataSourceIDataSourceHandler来作为服务暴露,同时调用方通过工厂类直接将IDataSourceHandler服务注入,就可以达到在调用方这边获取到的是DataSource的实例,但是需要注意的就是,由于ASF服务框架是动态随机加载各个组件,可能在服务被调用的时候尚未发布,因此需要在注入的时候设置为lazy-inittrue

<o:p> </o:p>

结论:

       Proxy被运用约来广泛,但是也会造成一些再运用Proxy代理的实例作为框架业务逻辑的情况,必须弄清楚情况然后选择如何调用和组装,同时作为服务暴露给第三方,尽量选择无状态的接口服务。

 
分享到:
评论

相关推荐

    spring 事务管理例子(TransactionProxyFactoryBean代理机制 和 tx/aop)

    适用企业系统的sturts1.2+spring2.0+jdbc 的架构。 通过TransactionProxyFactoryBean 代理机制和tx/aop两种方式来管理事务的详细demo

    spring proxy代理模仿

    spring proxy代理模仿 提练出来了

    spring-boot-data-source-decorator:与p6spy,datasource-proxy,flexy-pool和spring-cloud-sleuth集成的Spring Boot

    用于分布式跟踪的库(如果在classpath中找到)可启用jdbc连接和查询跟踪(仅适用于p6spy或datasource-proxy) 为什么不将DataSource包装在配置中? 除了使用库之外,您还可以手动包装DataSource ,但是该库还提供了...

    Spring源代码解析(五):Spring_AOP获取Proxy.doc

    Spring源代码解析(五):Spring_AOP获取Proxy.doc

    Spring示例_Printer_Spring_AOP_Spring_Proxy

    Spring示例_Printer_Spring_AOP_Spring_Proxy

    spring源码分析(1-10)

    Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源...

    SpringIOC,DI+dynamic proxy 实现盗版AOP

    SpringIOC,DI+dynamic proxy 实现盗版AOP的源代码

    spring2.5学习PPT 传智博客

    22.Spring集成的jdbc编码和事务管理 23.使用Spring注解方式管理事务与传播行为详解 24.使用Spring配置文件实现事务管理 25.搭建和配置Spring与Hibernate整合的环境 26.Spring集成的Hibernate编码与测试 27....

    Spring_0300_JDKProxy

    简单的动态代理实现代码!文档参考博文Spring学习(3)AOP初步—JDK动态代理

    spring框架手动提交事务,jdbctample

    注意:只是jdbc自带的jdbctample,不能 用于整合mybatis框架的事务,我整合了,事务不起作用!!!! 按老师的说法是基于xml方式,但不准确,因为也用到了注解 &lt;aop:aspectj-autoproxy proxy-target-class="true"&gt; ...

    datasource-proxy:为JDBC交互和通过代理执行查询提供侦听器框架

    数据源代理 关于 为JDBC API提供代理类,以拦截正在执行的查询和方法。 版本号 2.x (开发中) ... &lt; artifactId&gt;datasource-proxy [LATEST_VERSION] 最新版本是: 不依赖其他库,一切都是可选的。

    类似spring Aop的Proxy封装

    有一天在用回调模版的时候,忽然间又想到jdk自带的Proxy类似乎不是怎么好用,为何不把其做成回调模版呢,可以将其改造称类似spring Aop 代码如下: package com.fjx.proxy.up.test; import ...

    分布式事务实践 解决数据一致性

    介绍了Spring的事务机制、事物抽象、内部事务和外部事物,以及常用的几种事务管理的实现,包括DataSource、JPA、JMS、JTA都通过实例进行说明。还有XA以及两阶段提交,并通过实例演示了使用JTA,通过两阶段提交,实现...

    Nginx反向代理和proxy

    此文比较详细讲述了Nginx与proxy共同搭建反向代理服务的配置方法

    08spring4_dynamicproxy.rar

    // UserService proxy =(UserService)pih.getProxy(); // proxy.search(); ProxyInovationHandler ph =new ProxyInovationHandler(); ph.setTarget(new ArrayList()); List list =(List)ph.getProxy(); ...

    Spring开发指南

    事务管理 持久层封装 JDBC Hibernate in Spring ibatis in Spring Aspect Oriented Programming AOP 概念 AOP in Spring Dynamic Proxy 与Spring AOP CGLib 与 Spring AOP AOP 应用 DAO Support ...

    spring源码分析

    5.Spring源代码解析(五):Spring AOP获取Proxy 6. Spring源代码解析(六):Spring声明式事务处理 7. Spring源代码解析(七):Spring AOP中对拦截器调用的实现 8. Spring源代码解析(八):Spring驱动Hibernate...

    Spring源代码解析

    Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源...

    Spring源码学习文档,绝对值得好好研究~~

    Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):Spring声明式事务处理.doc Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的...

Global site tag (gtag.js) - Google Analytics