美文网首页Spring
【Spring】 11 - 关于 注解 配置 Spring AO

【Spring】 11 - 关于 注解 配置 Spring AO

作者: itlu | 来源:发表于2020-10-25 17:37 被阅读0次
  1. 问题 : 使用注解配置 Spring Aop 的四种通知类型实现事务控制,出现如下问题 :
  com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
  1. 原因:由于四种通知类型的执行顺序与 xml 配置方式的差异 ,可以将注解配置的方式理解为一个bug

  2. 正常使用 xml 配置 四种通知类型的执行顺序是 : 前置通知 后置通知/异常通知(当出现异常时) 最终通知。这是一种正常的情况。

     <aop:config>
        <aop:pointcut id="pc" expression="execution(* com.lyp.service.impl.*.*(..))"/>
        <aop:aspect id="txAspect" ref="txManager">
            <aop:before method="beginTransaction" pointcut-ref="pc"/>
            <aop:after-returning method="commitTransaction" pointcut-ref="pc"/>
            <aop:after-throwing method="rollbackTransaction" pointcut-ref="pc"/>
            <aop:after method="closeTransaction" pointcut-ref="pc"/>
        </aop:aspect>
    </aop:config>
  1. 使用注解配置四种通知类型的时候的执行顺序 :前置通知 最终通知 后置通知/异常通知(当出现异常时) 。此时最终通知优先于后置通知执行了,首先将连接释放,此时再进行提交,就是会出现上面的异常。
      /**
     * 开启事务
     */
    @Before("pc()")
    public void beginTransaction() {
        try {
            /* 设置事务提交方式为手动提交 */
            System.out.println("开启事务");
            cu.getTreadLocalConnection().setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务
     */
    @AfterReturning("pc()")
    public void rollbackTransaction() {
        try {
            /* 设置事务提交方式为手动提交 */
            System.out.println("回滚事务...");
            cu.getTreadLocalConnection().rollback();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 提交事务
     */
    @AfterThrowing("pc()")
    public void commitTransaction() {
        try {
            System.out.println("提交事务....");
            /* 设置事务提交方式为手动提交 */
            cu.getTreadLocalConnection().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放连接
     */
    @After("pc()")
    public void closeTransaction() {
        try {
            /* 设置事务提交方式为手动提交 */
            System.out.println("关闭事务....");
            cu.getTreadLocalConnection().close();
            cu.removeConn();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  1. 解决办法:使用环绕通知替换上面的配置
@Around("pc()")
public Object aroundAdvice(ProceedingJoinPoint pjp) {
        Object rs = null;
        try {
            Object[] args = pjp.getArgs();
            // 开启事务
            this.beginTransaction();
            // 执行代码
            rs = pjp.proceed(args);
            // 提交事务
            this.commitTransaction();
            return rs;
        } catch (Throwable t) {
            // 回滚事务
            this.rollbackTransaction();
            throw new RuntimeException(t);
        } finally {
            this.closeTransaction();
        }
    }

相关文章

  • 【Spring】 11 - 关于 注解 配置 Spring AO

    问题 : 使用注解配置 Spring Aop 的四种通知类型实现事务控制,出现如下问题 : 原因:由于四种通知类型...

  • 2019-08-10 spring

    spring 概述和基于 xml 的 ioc 配置基于注解的 ioc 和 ioc 案例基于注解的 ioc 和 ao...

  • SpringAOP使用

    目前 Spring AOP 一共有三种配置方式。 Spring 1.2 基于接口的配置:最早的 Spring AO...

  • Spring(二) 注解

    Spring(二) 注解 Spring中常用注解介绍 Spring中的注解配置和xml配置要实现的功能是一样的 注...

  • 02.Spring基础

    Spring简史: Spring1.x时代:xml配置 Spring2.x时代:注解配置(Jdk1.5引入注解),...

  • Spring注解

    Spring注解 Spring可以通过XML文件和注解来配置bean,本文就Spring中的注解进行简要学习 概述...

  • Spring注解配置工作原理源码解析

    【Spring实战】Spring注解配置工作原理源码解析

  • Spring_9 Spring基于AspectJ AOP 注解实

    Spring AOP 使用注解方式增强 配置spring.xml文件 在 spring.xml 中开启AOP注解。...

  • Spring注解开发

    2. Spring注解开发 2.1 Spring原始注解 Spring是轻代码而重配置的框架,配置比较繁重,影响开...

  • spring-ioc 注解

    spring-ioc 注解使用 配置扫描路径 添加注解 @Component("user") 使用 Spring ...

网友评论

    本文标题:【Spring】 11 - 关于 注解 配置 Spring AO

    本文链接:https://www.haomeiwen.com/subject/kfenmktx.html