现象
- 无法正常进行事务回滚,异常后,数据库依旧执行了修改。
- 无法显示事务管理的日志。
- 使用测试类,在测试类上面加上@Transactional去调用Service方法,事务就能正常回滚,并且有日志输出。
解决过程
解决事务问题
- 为了看清楚我在调用某个方法的时候,到底开没开启事务,我是用了TransactionSynchronizationManager来判断。它的isActualTransactionActive会返回一个Boolean类型的值,用于表示,当前是否开启了事务。这样,我在测试方法中,就能够直观的看到我的方法调用时,是否有事务正在运行。
- 接下来,我在shiro的realm中,在我注入的AppUserService上使用@Lazy懒加载这个Bean。懒加载能够使得这个Bean在第一次需要访问的时候才加载到容器当中。这里也还有其他的方法,我们后面进行详细讨论
- 然后,在application.yml配置mybatis的日志,最初我直接配置的是logging.level.com.fuchuang.race.mapper=debug,这里修改成直接配置Mybatis的日志:mybatis.configuration.log-impl。Mybatis的Log-imp有:LF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
问题解析
为什么使用Logging配置的日志不能够输出Mybatis的详细信息?
- logging.level是用于配置输出springboot的日志,它的底层是Commons-logging,不同于mybatis的日志,这里输出的是全局日志。
- mybatis配置日志使用log-impl:选择一种日志实现,用于输出Mybatis中的全部日志。
为什么不使用@Lazy注解AppUserService会导致事务开启失败?
相关知识点补充
引发@Transactional无效的常见原因
- 注解不能添加在非Public方法上
- 进行事务管理的方法,抛出的必须是uncheck的异常
- 启动器要添加@EnableTransactionManagement,开启事务管理。
- 数据库表的类型要是innoDB
Spring事务原理:基于AOP
核心类:TransactionAspectSupport
BeanPostProcessor
引发我的事务无效的原因:在Realm中注入了Service
- 解决手段有多种:
- 使用懒加载@Lazy
- 不注入Service,注入Dao
- 注入Service出错是因为Spring Bean的加载顺序问题