问题描述
遇到了一个spring配置事务不能生效的问题,在网上查了一下各种解决方案,但还是不能解决,不知道问题根源在哪里,请各位大神指点,非常感谢。<bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource"><property name="driver">......<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource"><ref bean="dataSource" /></property><property name="packagesToScan"><list><value>com.abc</value></list></property>......<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"><property name="sessionFactory" ref="mySessionFactory"></property></bean><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory"><ref local="mySessionFactory" /></property></bean><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="save*" /><tx:method name="*" read-only="true" propagation="REQUIRED" /></tx:attributes></tx:advice><aop:config><aop:pointcut id="serviceMethod" expression="execution(* com.abc.*.service.*.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /></aop:config>不知道是不是配置的问题,代码采用的是springMVC+spring+hibernate的框架,采用的是注解方式,service和DAO中都使用过注解定义事务,仍然没有作用,数据操作采用的是getHibernateTemplate().save...。 问题补充:java.lang.RuntimeException: 测试 at com.abc.forum.service.impl.TopicServiceImpl.save(TopicServiceImpl.java:25) at com.abc.forum.controller.TopicsController.addTopic(TopicsController.java:124) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)错误栈中都没有相关事务的类。
解决方案
事务生效的本质在于注解或者AOP的事务控制逻辑与代码中使用的逻辑在执行的过程中是否使用了相同的数据库连接&线程的控制,因此事务不能正确启用可能有如下几种原因:1)事务逻辑控制与代码使用的是不同的数据源:比如注解配置的是transactionManagerA ==> A的数据源,代码里面从数据源B获取连接,这时事务是不会启用的;2)使用了同一个数据源,但是使用的不是同一个连接:如使用了dataSource.getConnection直接获取连接,就不会启用事务,需要使用Spring-hibernate的框架提供的方式操作数据库;3)线程问题:AOP控制与逻辑代码获取连接实际上是通过ThreadLocal的方式共享链接的,失去了这个条件(比如你的代码里面New thread了),也是不会共享连接的。题主需要从Spring事务的原理出发,才能知道是为什么。
解决方案二:
1、在save方法后面加上REQUIRED2、在service实现类throw new RuntimeException()
解决方案三:
检查数据库是否支持事务,如果用的是MySQL,默认不支持事务。
解决方案四:
注解方式的事务不是这么配置的,<tx:annotation-driven transaction-manager="transactionManager"/>