SpringMVC事务失效的一种情况-bean加载顺序问题
2015-08-15 10:38
573 查看
首先给大家看一个范例java代理的范例:
base-package="..."/>而你期望这里直接就扫描所有的注解,那么恭喜你,你的事务就无效了,因为,在事务注册到Spring容器之前,你已经初始化了所有的bean,获取该bean就不会通过代理,事务就无从谈起了。因此,合理的配置方式是保证需要事务管理的bean的生成要后于事务的声明,具体方式有很多种,大家可以任意选择
public class MyInvocationHandler implements InvocationHandler { // 目标对象,也就是我们主要的业务,主要目的要做什么事 private Object delegate; /** * 和你额外需要做得事情,进行绑定,返回一个全新的对象(写法,基本上固定的) * * @param delegate * @return */ public Object bind(Object delegate) { this.delegate = delegate; return Proxy.newProxyInstance( this.delegate.getClass().getClassLoader(), this.delegate .getClass().getInterfaces(), this); } /** * 你刚才需要执行的方法,都需要通过该方法进行动态调用 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; // 执行前置的方法 UserDaoSupport.before(); // 通过反射,执行目标方法,也就是你的主要目的 obj = method.invoke(this.delegate, args); // 执行后置的方法 UserDaoSupport.after(); // 返回值给调用者 return obj; } } public class UserDaoSupport { public static void before(){ System.out.println("前置日记:打印、启动事务等.."); } public static void after(){ System.out.println("后置日记:打印、关闭事务等.."); } public static void other(){ System.out.println("做其他的事.."); } } @Test public void proxyTest() { UserDao userDao = (UserDao) new MyInvocationHandler().bind(new UserDaoImpl()); userDao.insert(); }事务其实就是这么回事,对于设置了事务的函数而言,其实就是SpringMVC生成一个代理,访问相应函数,这也就不难解释某种情况事务失效的原因了
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="get*" propagation="REQUIRED" rollback-for="java.lang.Exception" read-only="true"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="interceptorPointCuts" expression="execution(public * com.leon.web.service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" /> </aop:config>则com.leon.web.service包下的所有匹配上述三个方法名的函数都会被事务控制,但是现在就出现了一个问题,就是Spring 配置文件加载顺序问题,SpringMVC加载顺序如下:web.xml, *-servlet.xml, applicationContext.xml..... 如果在*-servlet.xml中定义了对applicationContext.xml中bean的ref,自然会往后找,但是如果没有,就正常的加载顺序,如在*-servlet.xml声明了<context:component-scan
base-package="..."/>而你期望这里直接就扫描所有的注解,那么恭喜你,你的事务就无效了,因为,在事务注册到Spring容器之前,你已经初始化了所有的bean,获取该bean就不会通过代理,事务就无从谈起了。因此,合理的配置方式是保证需要事务管理的bean的生成要后于事务的声明,具体方式有很多种,大家可以任意选择
相关文章推荐
- Zookeeper的Java客户端
- Java报错原因汇总
- Java RTTI与反射(参照Java编程思想与新浪博客)
- Java RTTI与反射(参照Java编程思想与新浪博客)
- Eclipse文件编码设置的问题
- Java中P 4000 reparedStatement和Statement的用法区别
- Java基础04 封装与接口
- java基础复习
- 二项堆 之 Java的实现
- 如何在eclipse中安装Jess
- java中throws和throw的区别
- Java基础03 构造器与方法重载
- Eclipse工程出现红色感叹号
- java中Statement详细用法
- Java 创建型模式:单态模式,原型模式,工厂方法,抽象工厂,建造者模式
- Spring常用annotation标签
- 配置java环境变量
- eclipse在线安装插件
- java线程池的基本使用
- 【Java】-基础-Swing介绍