想要了解更多,加QQ群72132378
基础真的太重要了,这个问题困扰了我大半天。
开始的时候,不管我使用注解还是配置文件的形式,事务都不好使,也就是出异常了事务不回滚。因为首先怀疑的是我自己写的代码有问题,所以搜了好多资料,一一对比,没有发现任何问题,后来才发现,原来是spring扫描的先后顺序导致的问题。
下面说说我的解决方式:
首先配置扫描范围如下
<context:component-scan base-package="com.test.*" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
然后配置事务如下:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- 下面这一段才是关键 -->
<context:component-scan base-package="com.test.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
然后我的问题就解决了。
原理目前我还没有研究,就看到网友这么写的:
Spring会扫描并优先注册默认的bean(当然包括标记为@Service的bean),这样,标记为@Transactional的service由于transaction manager尚未注册而未能生效,导致事务管理失效。
原理是:标记为@Transactional的service会wrap为经过transactional proxied(不管是CGLIB based或是JDK based)的bean,而不再是纯的service;
有时间在研究一下,怎么使用标签 use-default-filters="false" 来实现,因为我觉得这个才是解决的根本,我上面的方法只是让spring重新去扫描了一次,不是最优解决方式。