我先说下我的环境差异吧:springboot的版本是一样的2.0
数据库我的是mysql8.0
依赖是<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency>
我在service层用了@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
但是没有生效我以为没有开启事务,还在启动入口加了@EnableTransactionManagement
都没有回滚
我最后在切面里改了点东西就可以了,我是这样改的catch(Exception e){ log.error("日志记录发生错误, errorMessage: {}", e.getMessage()); throw e; }
然后发现事物就起作用了,不知道这样改行不行,springboot的事务机制是不能通过切面拦截吗?
希望老师解决下我的问题,谢谢啦~
重点就在于你切面里面的throw e;应该@Transactional原理也是切面捕获异常,如果你的切面在@Transactional之前将异常给捕获了并且不抛出,那么事务就会失效。
你可以写这么两段代码(以下为伪代码)比较一下:
@Transactional try{ install 1/0 }catch(...){ sout("异常") }
@Transactional try{ install 1/0 }catch(...){ sout("异常") throw new Exception() }
第一段代码因为已经把异常捕获了,不抛出,所以事务失效。
第二段代码就可以成功。
由此问题可以得到一个开发规范就是,项目中必须要有自定义异常,在每一个try catch里面都必须抛出一个自定义异常
1、只有在运行时异常时才支持回滚
2、数据库引擎是InnoDB才支持事物