1. 背景
基于SSM架构的项目,在服务层方法添加了@Transactional注解,applicationContext开启了注解:
<!-- 事物管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 -->
<tx:annotation-driven transaction-manager="transactionManager" />
案例说在服务层添加了@Transactional注解的方法应该具备事务的原子性,结果无效,查看日志发现有:
Closing non transactional SqlSession
1
这个也提示事务没有起作用。
2. 原因
幸好有SVN,发现之前做了一个修改,就是把对服务层的扫描配置从applicationContext.xml移到了spring-mvc.xml。
<!--该配置原来在applicationContext.xml 作用是自动扫描com.easy.service包下的类 并作为bean加载到容器-->
<context:component-scan base-package="com.easy.service" />
将这句配置移回applicationContext.xml,事务果然生效。
3. 分析
仔细想了下,SSM架构下,Spring是一个容器,通过applicationContext.xml配置,SpringMVC算子容器,通过spring-mvc.xml配置。
子容器可以访问父容器中的bean,但是父容器不能访问子容器的bean,就跟继承关系似的。
所以父容器中定义的事务管理bean就不知道子容器中扫描的com.easy.service包下的类情况了。