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

编程教程 > Java > Spring (2224) 2024-11-26 14:39:04

出现@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


评论
User Image
提示:请评论与当前内容相关的回复,广告、推广或无关内容将被删除。

相关文章
出现@Transactional事务不生效原因shiro 的Realm 中注入了用到事务的service,例如下面的​ /** * 自定义权限认证器 * 自定义实现Realm,实现自定义获取...
事务有四个特性:ACID原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。一致性(Cons
引言    通过之前spring boot mybatis 整合的讲解: spring boot mybaties整合  (spring boot mybaties 整合 基于Java注解方式写...
spring boot框架整合MyBatis数据库暂时选用MySQL
spring boot入门,spring boot是一个崭新的spring框架分支项目,本文讲解其属性配置相关
spring boot mybatis 整合使用讲解介绍,spring boot与MyBatis的使用讲解介绍。spring boot mybatis xml mapper方式的入门和通过一个简...
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框架分支项目,本文讲解spring boot中controller的常用注解使用
spring boot是一个崭新的spring框架分支项目,本文讲解基本的数据库配置
spring boot 1.5整合redis实现spring的缓存框架,spring boot,redis
Spring Boot validation整合hibernate validator实现数据验证,Spring Boot validation使用说明,Spring Boot validat...
spring boot框架中常见注解说明,spring boot,JAVA
Spring Boot 2.0 Redis整合,通过spring boot 2.0整合Redis作为spring缓存框架的实现。