参考这个文档
http://liuu.iteye.com/blog/422810
http://www.51cto.com/specbook/223/39480.htm
http://www.iflym.com/index.php/code/proxy-created-of-subclass-extended-proxied-class-by-spring.html
http://www.iflym.com/index.php/code/proxy-method-intercept-of-subclass-extended-proxied-class-by-spring.html
http://www.iteye.com/problems/71797
http://www.iteye.com/topic/40553
http://www.redsaga.com/spring_ref/2.5/html/aop-api.html
http://japi.iteye.com/blog/285800
或许按照回复的办法,把参考文档中的两个方法放到不同类中。
很不幸,我也遇到了这个问题。
但是按照作者的方法,修改aop:config如下:
<aop:config proxy-target-class="true">
<aop:pointcut id="allServiceMethod" expression="execution(* *..service.*Service.*(..)) " />
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
</aop:config>
其中service包下的是接口,具体实现在service.spring包下面。
修改后还是不行。
但改成这样就好了:
<aop:config>
<aop:pointcut id="allServiceMethod" expression="execution(* *..service.*Service.*(..)) and execution(* *..service.*.*Service.*(..))" />
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
</aop:config>
也就是在接口和实现类都声明在事务中。
如果只是在声明接口或者实现类单方面加都不行。
修改后虽然能写数据库,但是事务不生效!!!很奇怪的问题!!!!
我的情况如下:
action调用service.A ;serviceA调用service.B;
事务设置采用声明式事务
其中service.A的方法属于只读事务;B方法属于读写事务;然后B又调用service2.B,真正写数据库的是service2.B。
调用时报错,只读事务,不能修改数据。
查看堆栈发现,代理只在调用A时加了事务拦截,在A调用B是没加事务拦截;
堆栈大概如下,注意红色字体是连在一次调用,中间没有任何拦截:
at xxx.service.spring.ServiceImpl.B(ServiceImpl.java:1245)
at xxx.service.spring.ServiceImpl.A(ServiceImpl.java:1555)
at xxx.service.spring.ServiceImpl$$FastClassByCGLIB$$5bad9769.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at xxx.action$$EnhancerByCGLIB$$f76d57d.xxx(<generated>)
如果是required,则事务依旧使用原来的事务,所以A只读,导致B只读,把service2.B改成REQUIRED_NEW就好了但没什么特殊要求都应该使用REQUIRED。
这个问题引起的原因是这个配置
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
导致A变成只读,范围太大了。
上面改后,service.B中依旧是只读事务。
测试发现AOP不能嵌套,不管JDK还是cglib都一样,如果同一对象OBJ的第一个函数A没有使用事务,那么A里面调用的OBJ.B方法,尽管B方法已经声明了事务,但一样不生效,因为AOP没有对A调用B是做拦截,也不可能做,B在OBJ中调用,不是在代理中调用,代理没法做。跨类到可以。
只读原因分析:
所以service.A只读事务,导致service.A调用B时,没经过AOP事务拦截,也就是service.A和service.B在同一个事务中,B就是只读事务,而当B调用service2.B时,如果service2.B是REQUIRED时,尽管service2.B的AOP拦截生效,但是REQUIRED命令service2.B直接使用已有事务,导致service2.B中也是只读事务。
把
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
去掉或者细化就好了
分享到:
相关推荐
AOP 是 OOP 的补充和完善,可以解决 OOP 中的缺陷,例如日志功能、安全性、异常处理和透明的持续性等横切关注点。 AOP 的核心思想是将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。AOP 技术可以将软件...
Spring的声明式事务管理是采用AOP(Aspect-Oriented Programming,面向切面编程)实现的。...若采用AOP,则可以避免以上缺陷。 作者博客的示例代码:http://legend2011.blog.51cto.com/3018495/1239139。
在缺陷管理系统中,Spring可以用来管理对象之间的依赖关系,例如数据库连接池、事务管理器等,通过DI使得这些服务易于测试和替换。AOP则可用于日志记录、权限验证等横切关注点,提高代码的模块化和可维护性。 ...
- **Spring**:这是一个全面的Java企业级应用开发框架,提供了依赖注入(DI)、面向切面编程(AOP)、数据访问、事务管理等功能。Spring还包含了Spring MVC,可以与Struts结合使用,提供更强大的Web应用支持。 2. ...
1. **Spring框架**:Spring是Java企业级应用的核心框架,提供了依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)等特性,使得开发者可以更方便地管理对象和处理事务。...
面向切面编程则允许开发者将横切关注点(如日志记录和事务管理)与业务逻辑分离,从而实现更好的模块化。 #### 1.2 Spring MVC框架 Spring MVC是Spring框架的一个模块,专门用于构建Web应用程序。它遵循模型-视图-...
此外,Spring还提供了事务管理、数据访问集成、Web应用框架等一系列功能。 3. **Spring MVC**: Spring MVC是Spring框架的一部分,用于构建Web应用。它通过DispatcherServlet接收请求,Controller处理业务逻辑,...
同时,Spring还提供了AOP(Aspect Oriented Programming,面向切面编程)功能,用于实现如日志、事务管理等跨切面的逻辑。 2. SpringMVC:SpringMVC是Spring框架的一部分,专门用于构建Web应用程序。它遵循MVC...
1. **Spring框架**:Spring是Java企业级应用的核心框架,提供了依赖注入(DI)和面向切面编程(AOP)等核心功能,简化了开发流程,增强了代码的可测试性。在这个项目中,Spring可能用于管理对象的生命周期和提供事务...
AOP的核心思想是模块化横切关注点,如日志、事务管理和安全性,从而提高代码的可维护性和可复用性。书中通过真题解析,介绍了AOP的基本概念、实现机制以及在实际开发中的应用场景。 二、系统安全架构设计及其应用 ...
HibernateDaoSupport提供了基于AOP事务的自动处理,程序员完全可以不用理会事务的开始与提交,它会自动完成SessionFactory的注入和事务的注入。 24.3 Spring对Hibernate的简化 24.3.5 HibernateDaoSupport ...
利用 AOP,开发者可以实现 POJO 业务对象的宣告式事务管理以及其他跨行业的企业服务。 框架的设计目标 该框架的设计目标是面向企业的 Web 应用,这些应用在 Java EE 的先进功能和分布式功能上并不需要太多。在对 ...
言归正传Spring+Struts+Hibernate是越来越少了Spring+SpringMVC+Mybatis的更多Spring,怎么都得用的,IOC,AOP,事务管理都太宝贝了。struts太重太繁琐,SpringMVC各方面,完胜,没接触过struts2,不评。Hibernate太...
传统的性能数据采集方法是通过修改源代码来埋桩,但这存在诸多缺陷,例如增加了代码维护难度,可能引入新的bug,且难以适应快速迭代的开发环境。针对这些问题,论文提出了使用面向切面编程(AOP)对Android源代码...
AOP的核心概念是切面,它封装了横切关注点,如日志、事务管理等。而TestNG是一款流行的Java测试框架,它比JUnit提供了更多的特性,如支持多线程测试、灵活的测试配置、更丰富的报告等。ajtest库的目标是在没有Java...
Nutz的Dao模块提供针对JDBC的薄封装、事务模板和无缓存支持,为数据库操作带来了便捷。Ioc模块采用JSON风格的配置文件,支持声明式切片,使得依赖注入更为简洁。Mvc模块则采用注解风格的配置,内置了多文件上传功能...
AOP则提供了模块化横切关注点(如日志、事务管理)的方式。此外,Spring还包含对数据访问、Web应用、消息处理等的支持。 **SpringMVC**: SpringMVC是Spring框架的一部分,专门用于构建Web应用。它采用模型-视图-...