Spring事务不起做用的缘由

一、确认建立的MySQL数据库表引擎是InnoDB,MyISAM不支持事务。

二、确认调用的类是由Spring容器管理的代理类。

AopUtils.isAopProxy(Object object)
AopUtils.isCglibProxy(Object object) //cglib
AopUtils.isJdkDynamicProxy(Object object) //jdk动态代理
<aop:config proxy-target-class="true" />可强制cglib代理

三、调用的方法必须是public,不然事务不起做用。这一点由Spring的AOP特性决定的。

四、Spring切点是否配置错误,或使用了SpringMVC,多是context:component-scan重复扫描引发的。

五、抛出一个runtimeException才能回滚,Spring使用声明式事务处理,默认状况下,若是被注解的数据库操做方法中发生了unchecked异常,全部的数据库操做将rollback;若是发生的异常是checked异常,默认状况下数据库操做仍是会提交的。若是checked异常也想回滚怎么办,注解上面写明异常类型便可@Transactional(rollbackFor=Exception.class) 相似的还有norollbackFor,自定义不回滚的异常。

六、Spring的事务传播策略在内部方法调用时将不起做用。

public int save(String name, int age) throws Exception {
  insert(name, age);
  return 1;
}

@Transactional
public void insert(String name, int age){
  jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
  jdbcTemplate.update("insert into user(id,name,age)values(2,'"+name+"',"+age+")");
}

七、集成了Shiro,并将以下代码与Shiro配置放在一个文件中。可参见 https://blog.csdn.net/m0_37962779/article/details/78605478 。解决办法是将以下代码与Shiro配置做为两个@Config分别配置。java

@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
  DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
  advisorAutoProxyCreator.setProxyTargetClass(true);
  return advisorAutoProxyCreator;
}

@Bean
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
  return new LifecycleBeanPostProcessor();
}

 

另外经过开启事务日志能够较方便的发现问题。spring

<logger name="org.springframework.transaction" level="TRACE"/>