整合shiro问题----数据库事务失效

spring事务管理

spring事务管理支持两种类型。一种是编程式的事务类型,另外一种是声明式的事务类型。但是无论哪一种底层都采用spring事务管理器进行统一管理。
spring事务管理介绍我之前写的还算比较详细:spring事务管理介绍

spring事务失效的原因

  • 没有开启事务 @EnableTransactionManagement (如果使用springboot会自动配置开启该注解,注册事务管理器和事务增强器)
  • 异常类型不对,spring事务默认只对RuntimeException进行回滚。
  • 只能在作用在public方法上(SpringAOP基于代理的局限性)
  • 子线程中无法使用事务,也就是你自己new出来的线程,异步执行的任务无法使用事务。
  • 通过this调用当前类的方法。因为this调用是真实对象,并不是通过代理对象调用。例如:如果是一个不带事务的方法调用该类的带事务的方法,直接通过this.xxx()调用,而不生成代理事务。

总结就是一句话:既然spring事务依赖于动态代理,那么事务能否失效,就开是否生成了代理对象。

springboot 整合shiro 事务失效了

如果你的项目整合了shiro,那么注意观察启动日志是否打印了类似于这样的语句:

 Bean 'sysUser' of type [com.sun.proxy.$Proxy87] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

这句话的意思就是SysUser对象被提前初始化了,不会被spring后置处理器拦截处理,导致出现问题,例如不能够被自动代理。
如果你看明白了这句话,我想也大概明白了整合shiro时候为什么事务会失效了,因为spring事务依赖于AOP代理技术实现。

整合Shiro时候,你在自定义的Realm中自动注入了UserService,UserService在这里被提前初始化了,所以事务失效了。

具体原因:ShiroFilterFactoryBean实现了后置处理器接口,在加载bean后置处理器前会加载Configuration配置类,导致ShiroFactoryBean被初始化了,也就是在这里提前实例化了相关的bean。

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

解决办法

在自定义Realm的中注入UserService时候,使用懒加载@Lazy。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值