首先,@Transactional注解常见的几个失效原因:
1. 抛出了checked异常:需要指定(rollbackFor=Exception.class)解决
2. 注解标注的方法不是public
3. 数据表(Mysql) 不是innodb引擎
4. 同类非public方法调用注解方法
5. 未配置<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
6. 未开启扫描<context:component-scan ...>
有一个老业务采用的是springMVC,而上面的配置均是正常的,但是抛出异常后回滚却失效了!这就很诡异,google后发现了有问题。
问题在于,spring-servlet.xml扫描到了Service里的这些注解,这是我的配置
<context:component-scan base-package="com.xxx">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
没有开启use-default-filters="false", 而这个值默认是为"true"的,即扫描所有@Component、@Service、@Reposity。
这个注解应该只在application.xml里扫描到。若spring-servlet.xml、application.xml都扫描到相同的bean, spring会默认使用spring-servlet.xml的bean。
而spring-servlet.xml一般只是配置Servlet相关,这个xml里并没有开启<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>。
在spring-servlet.xml加上use-default-filters="false",让它只扫描Controller相关注解,解决这个问题