第一步,修改spring的配置文件和springmvc的配置文件
--------------------------------applicationContext.xml
<context:annotation-config/>
<context:component-scan base-package="com.xxx">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
--------------------------------applicationContext-mvc.xml
<context:component-scan base-package="com.xxx">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
解释:SpringMVC配置文件产生的环境是Spring环境的子环境,会有一些冲突:SpringMVC的环境会接管Service注解,而这会使transactional失效。
所以我们要做的就是在把Service注解排除出SpringMVC环境(exclude-filter),这样就可以让其交给Spring环境处理了,就不会让Transactional注解失效了;同时Spring配置中排除Controller注解,让其交给SpringMVC环境去处理;
第二步,修改Spring配置文件中hibernate的属性设置
在@Transactional注解的方法中,session的获取通常是通过sessionFactory.getCurrentSession()来获取的。而通常对应的hibernate属性设置是如下:
<prop key="hibernate.current_session_context_class">thread</prop>
报错中,得不到 active transaction ,通常就是这个设置错误。改为如下即可:
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
详情请查看该文 如果你报createSQLQuery is not valid without active transaction,请看这里
第三步,查看是否漏掉开启注解的配置
<tx:annotation-driven transaction-manager="txManager" />
txManager是自定义的已配置好的事务管理器。
另外,DaoImpl类上用@Repository注解,ServiceImpl类上用@Service注解。
只要注意以上三步,一般就可以解决@Transactional注解失效的问题了。
该文也可以参考 http://www.verydemo.com/demo_c143_i3007.html
PS:进一步思考,@Transactional加在@Service注解的类的方法中,就应该在springmvc配置文件中exclude-filter
如果加在@Repository注解的类中的方法中,也应该还exclude-filter org.springframework.stereotype.Repository 应该是这样,未测试。
项目记录:spring+springmvc 项目中 @Transactional 失效的解决方法,布布扣,bubuko.com