Spring Boot Mybatis Shiro 中出现事务不生效原因及解决办法

位置:首页>文章>详情   分类: 教程分享 > Java教程   阅读(1153)   2023-03-28 11:29:14

出现@Transactional事务不生效原因

shiro 的Realm 中注入了用到事务的service,例如下面的

​
/**
 * 自定义权限认证器
 * 自定义实现Realm,实现自定义获取登录信息进行登录鉴权和获取权限信息进行权限鉴权
 */
public class UserRealm extends AuthorizingRealm {
    //超管账号
    @Value("${super.user}")
    String su;
    
    
    @Autowired
    SystemUserService systemUserService;
​
   
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       // TODO CODE ...
        return info;
    }
​
    /***
     * 登录鉴定(就是鉴定用户是否登录)
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       // TODO CODE ...
        return info;
    }
}
​

按上方代码使用,SystemUserService 这个service中所有的事务都将不会生效。

原因细节

  1. 首先我们在项目整合Shiro的时候通过ShiroConfig做了一些配置,其中一项包括Shiro的授权认证器MemberAuthorizingRealm。

  2. 在UserRealm中我们通过@Autowired注入了本篇的主角SystemUserService。

  3. Spring启动的时候,配置相关的都是优先初始化的,在初始化UserRealm的时候发现需要注入一个SystemUserService对象,容器里肯定是没有的,那么就提前将其初始化了。此时如果在MemberService还有通过@Autowired注入的其他依赖,那么会一并初始化,依赖中要是还有依赖会继续递归初始化,这样下来会导致一系列的实例都是没有被代理的。

  4. 但是这时候Spring中创建代理的处理器是还没有的,导致SystemUserService的BeanPostProcessor中没有AbstractAutoProxyCreator这个对象,后面整个BeanPostProcessor列表执行的时候没有为其创建代理。

  5. Spring中的数据库事务都是需要代理支持的,所以MemberService中不能开启事务。

 

解决办法

方法一(推荐):

Realm中注入的service上面添加@Lazy注解

/**
 * 自定义权限认证器
 * 自定义实现Realm,实现自定义获取登录信息进行登录鉴权和获取权限信息进行权限鉴权
 */
public class UserRealm extends AuthorizingRealm {
    //超管账号
    @Value("${super.user}")
    String su;
    
    @Lazy
    @Autowired
    SystemUserService systemUserService;
​
   
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       // TODO CODE ...
        return info;
    }
​
    /***
     * 登录鉴定(就是鉴定用户是否登录)
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       // TODO CODE ...
        return info;
    }
}

 

方法二:

单独创建一个service直接和mapper打交道,然后注入到Realm

 

方法三:

通过spring application getBean获取 service

地址:https://www.leftso.com/article/789.html

相关阅读

引言    通过之前spring boot mybatis 整合的讲解: spring boot mybaties整合  (spring boot mybaties 整合 基于Java注解方式写...
出现@Transactional事务不生效原因shiro 的Realm 中注入了用到事务的service,例如下面的​ /** * 自定义权限认证器 * 自定义实现Realm,实现自定义获取...
spring boot框架整合mybaties数据库暂时选用MySQL
1.开启事物通过注解开启@EnableTransactionManagement 提示: Spring Boot  以Spring 5.0为基础的版本无需注解自动开启事物2.测试事物首先查询数据...
简述本文主要通过一个简单的例子模拟实现秒杀情景,其中主要使用Redis事物进行实现spring boot为提供方便的环境
Spring Boot 2.0,Spring框架的Spring Boot 中的Spring Boot Actuator变化讲解。并且了解如何在Spring Boot 2.0中使用Actuator...
Spring Boot 2.0 绑定properties属性资源文件 Spring Boot 2.0 读取properties配置文件值 Spring Boot 2.0获取properties配...
spring boot入门,spring boot是一个崭新的spring框架分支项目,本文讲解其属性配置相关
spring boot 1.5整合redis实现spring的缓存框架,spring boot,redis
1.概述本文继续使用spring boot 和Spring Security系列进行注册,并着重于如何正确实现角色和权限