SpringBoot + Shiro导致 @Transactional 事务 和 @Async 多线程 失效问题

我们使用的 mongoD B4.0副本集 ,正常是支持事务操作的,但是开发运维两年
,某一次发生异常但是事务并没有回滚,导致数据对不上,意识到需要验证下事务是否还生效,单元测试验证 @Transactional 并未生效,查找原因,一开始以为是mongo的问题,但是两年前开始使用mongo就验证过了事务,一开始网络上找的答案都是如何配置,并未有效果,后来创建了个简单的项目,只引入相同版本spring data mongo 依赖事务生效,同时 @ASpringBoot + Shiro导致 @Transactional 事务 和 @Async 多线程 失效问题

后来 感觉问题有三种可能

  1. 依赖冲突
  2. 改动过spring data mongo的源码 ,因为当时那个版本aggregate关联源码会报错,还有 保存string到数据库里是 ObjectId类型,不方便关联
  3. bean冲突

找问题 重新拉取了一样项目, 删减 依赖 改动源码 发现不是 这两个问题

然后只能一点一点删除配置的类 依赖 以及相关代码 最后发现 是shiro的问题
(此阶段 用了 两天)

就上网搜索 springboot + shiro 导致事物不生效的问题,后来找到几个博客,找到了答案

解答文章链接

总结下来就是:
由于ShiroFilterFactoryBean实现了FactoryBean接口,所以它会提前被初始化。又因为SecurityManager,SecurityManager依赖于Realm实现类、Realm实现类又依赖于UserService,所以引发所有相关的bean提前初始化。

ShiroFilterFactoryBean -> SecurityManager -> Realm实现类 -> UserService

但是此时还只是ApplicationContext中registerBeanPostProcessors注册BeanPostProcessor处理器的阶段,此时AnnotationAwareAspectJAutoProxyCreator还没有注册到BeanFactory中,UserService无法享受到事务处理!
就是说在realm中注入的所有service都会提前加载,连带注入的service中,如果还有其他service注入也会提前加载,无法享受事务处理。

解决方案:

1.在realm中注入service时,加上@lazy注解
2.不在realm注入service

@Async 注解也需要 懒加载 ,要不可能会失效

希望可以帮助到你!