zoukankan      html  css  js  c++  java
  • 解决@Transactional事务在类内部方法调用不生效

    代码示例


    UserService测试接口类
    
    package cn.sw.study.web.service;
    
    /**
    
     * Created by shaowei on 2017/4/26.
    
     */
    
    public interface UserService {
    
        void addInfo();
    
        void addOne();
    
    }
    UserServiceImpl测试实现类
    
    package cn.sw.study.web.service.impl;
    
    import cn.sw.study.web.dao.UserMapper;
    
    import cn.sw.study.web.model.User;
    
    import cn.sw.study.web.service.UserService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import org.springframework.stereotype.Service;
    
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Date;
    
    /**
    
     * 用户业务类
    
     * Created by shaowei on 2017/4/26.
    
     */
    
    @Service("userService")
    
    public class UserServiceImpl implements UserService{
    
        @Autowired
        UserMapper userMapper;
    
        public void addInfo() {
            addOne();
    
        }
    
        @Transactional
        public void addOne() {
            User record = new User();
    
            record.setLoginName("tom");
    
            record.setPwd("111111");
    
            record.setMobile("13913913913");
    
            record.setUsable(1);
    
            record.setCreateTime(new Date());
    
            userMapper.insertSelective(record);
    
            int i = 1/0;    // 测试事物的回滚
    
        }
    
    }

    现象描述


    addInfo方法上没有事务注解,addOne方法上有事务注解,此时运行addInfo调用addOne方法,不会产生事务,测试数据遇到异常没有回滚。如果从外部类直接调用addOne方法,则事务是可以正常生效的。

    解决方案


    使用AopContext.currentProxy()来获取代理类再调用,如下

    UserServiceImpl测试实现类
    
    package cn.sw.study.web.service.impl;
    
    import cn.sw.study.web.dao.UserMapper;
    
    import cn.sw.study.web.model.User;
    
    import cn.sw.study.web.service.UserService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import org.springframework.stereotype.Service;
    
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Date;
    
    /**
    
     * 用户业务类
    
     * Created by shaowei on 2017/4/26.
    
     */
    
    @Service("userService")
    
    public class UserServiceImpl implements UserService{
    
        @Autowired
        UserMapper userMapper;
    
        public void addInfo() {
            ((UserService)AopContext.currentProxy()).addOne();
        }
    
        @Transactional
        public void addOne() {
            User record = new User();
    
            record.setLoginName("tom");
    
            record.setPwd("111111");
    
            record.setMobile("13913913913");
    
            record.setUsable(1);
    
            record.setCreateTime(new Date());
    
            userMapper.insertSelective(record);
    
            int i = 1/0;    // 测试事物的回滚
    
        }
    
    }

    新问题


    再次运行,如果没有添加expose-proxy="true"这个属性(暴露代理对象),则会报错

    java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.

    新问题解决:springboot中如何配置aop动态代理模式(转载自:http://tingcream.com/blogArticle/detail/fd08e233b37844bca556ee393e46a928


     

    第一种方式:

    在application.yml中有以下配置

    spring:
      aop:
        #auto: true #默认为true,可省略
        proxy-target-class: true # 默认为false即JDK动态代理,我们一般要设为true,使用CGLIB代理

    这种方式只能将代理模式修改为了CGLIG,但是不能设置暴露cglib代理的目标对象。

    第二种方式:

    在springboot启动类上标记这个注解

    @EnableAspectJAutoProxy(exposeProxy=true,proxyTargetClass=true) 

    同时,排除 AopAutoConfiguration.class的自动化配置

    很好,这种方式同时设置exposeProxy为true和proxyTargetClass为true,即强制采用cglib代理,和暴露cglib代理的目标对象。

    第三种方式:

     在springboot启动类上引入spring.xml配置文件

    @ImportResource({"classpath:/spring.xml"})

    同时,排除 AopAutoConfiguration.class的自动化配置

    在spring.xml 配置文件中配置

      <!--1 aspectj 切面的支持 ,强制使用cglib,并暴露cglib代理的目标对象-->
          <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>  
          <context:annotation-config />  

  • 相关阅读:
    中国AI觉醒 阿里王坚:云智能将成为大趋势
    中国AI觉醒 阿里王坚:云智能将成为大趋势
    如何设计scalable 的系统 (转载)
    如何设计scalable 的系统 (转载)
    如何设计scalable 的系统 (转载)
    如何设计scalable 的系统 (转载)
    odoo开发笔记--模型中常用的方法
    odoo开发笔记--模型中常用的方法
    odoo开发笔记--模型中常用的方法
    用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
  • 原文地址:https://www.cnblogs.com/wly1-6/p/14583491.html
Copyright © 2011-2022 走看看