一、問題描述
1、項目架構:SpringBoot+Shiro+mybatis+mysql
2、問題:在Service層對數據庫進行持久化操作的時候,遇到異常發現事務沒有回滾
錯誤日誌:
20:39:07.007 DEBUG org.mybatis.spring.SqlSessionUtils 148 registerSessionHolder - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@be0c571] was not registered for synchronization because synchronization is not active
20:39:07.018 DEBUG org.mybatis.spring.transaction.SpringManagedTransaction 87 openConnection - JDBC Connection [HikariProxyConnection@50504791 wrapping com.mysql.jdbc.JDBC4Connection@7f5c5cc3] will not be managed by Spring
事務沒有被spring管理
二、問題排查
在網上查了很多資料,總結了以下可能造成事務失效的原因
1、對應方法上面是否加上了@Transactional註解
2、方法是否是public方法
3、是否對方法進行了異常捕獲,是否拋出的異常爲非運行異常,因爲@Transactional默認是在遇到運行異常時纔會進行回滾,如果對方法進行了異常捕獲或拋出異常爲非運行異常都不會回滾,需要在@Transactional註解增加屬性@Transactional(rollbackFor=Exception.class)
4、如果使用的mysql數據庫,檢查下數據庫是否用的是InnoDB引擎,如果引擎沒有問題檢查innoDB變量值have_innodb 是否開啓,查詢語句 SHOW VARIABLES LIKE 'have_%'
5、還有一種常見問題,如果使用的是Spring+SpringMVC架構,SpringMVC只用掃描Controller層,檢查下是否掃描了其他的包,造成了重複掃描。
6、最後一個原因,項目中使用了Shiro權限管理,並且調用了對應的Service,shiro 和 spring都會對該Service進行初始化,shiro在spring前就進行了初始化,從而造成了事務失效。
參考文章:https://blog.csdn.net/finalcola/article/details/81197584