springboot整合shiro后,出现的蜜汁@Transactional无法开启事务错误的解决过程心得

现象

  1. 无法正常进行事务回滚,异常后,数据库依旧执行了修改。
  2. 无法显示事务管理的日志。
  3. 使用测试类,在测试类上面加上@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无效的常见原因
  1. 注解不能添加在非Public方法上
  2. 进行事务管理的方法,抛出的必须是uncheck的异常
  3. 启动器要添加@EnableTransactionManagement,开启事务管理。
  4. 数据库表的类型要是innoDB
Spring事务原理:基于AOP

核心类:TransactionAspectSupport
BeanPostProcessor

引发我的事务无效的原因:在Realm中注入了Service
  • 解决手段有多种:
    1. 使用懒加载@Lazy
    2. 不注入Service,注入Dao
  • 注入Service出错是因为Spring Bean的加载顺序问题

总结

shiro的ShiroFactoryBean在被初始化的时候,依赖了realm里面的UserService,它也被初始化,但是由于spring对Bean的初始化是分阶段的,这个时候对UserService进行增强的那个PostBeanProcessor还没有被初始化,所以此时的UserService就没用增强,也就没有事务管理功能。把service替换成mapper,或者把service换成懒加载就可以解决这个问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值