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"/>
相關文章
相關標籤/搜索