Can‘t call commit when autocommit=true;使用注解配置aop问题解决

本文详细介绍了如何使用注解配置AOP实现事务管理,包括@Pointcut定义切入点、@Before开启事务、@AfterReturning提交事务、@AfterThrowing回滚事务及@After释放连接。并针对运行时出现的Can't call commit when autoCommit=true错误,提供了解决方案,通过使用@Around环绕通知重新配置事务流程。

使用注解配置aop,如图所示

  @Pointcut("execution(* cn.service.impl.*.*(..))")
    private void pt1() {
    }

    /**
     * 开启事务
     */
    @Before("pt1()")
    public void beginTranction() {
        try {
            connectionUtils.getThreadConnection().setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 提交事务
     */
    @AfterReturning("pt1()")
    public void commit() {
        try {
            connectionUtils.getThreadConnection().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务
     */
    @AfterThrowing("pt1()")
    public void rollback() {
        try {
            connectionUtils.getThreadConnection().rollback();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放连接,并不是真正的关闭,而是将连接还回池中
     */
    @After("pt1()")
    public void release() {
        try {
            connectionUtils.getThreadConnection().close();
            connectionUtils.removeConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

运行后,报错如图所示

java.sql.SQLException: Can't call commit when autocommit=true
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:930)
	at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1535)
	at com.mchange.v2.c3p0.impl.NewProxyConnection.commit(NewProxyConnection.java:803)
	at cn.utils.TransactionManager.commit(TransactionManager.java:39)

经过查找资料,发现这是由于使用注解配置aop时,事务的执行顺序出错导致,@After在@AfterReturning之前执行,导致connection被释放掉,故被认为事务已被自动提交,用环绕通知配置即可解决这一问题,配置如下


    @Around("pt1()")
    public Object aroundAdvice(ProceedingJoinPoint pjp) {
        Object reValue = null;
        try {
            //获得参数
            Object[] args = pjp.getArgs();
            //开启事务
            this.beginTranction();
            //执行方法
            reValue = pjp.proceed(args);
            //提交事务
            this.commit();
            //返回值
            return reValue;
        } catch (Throwable e) {
            //回滚
            this.rollback();
            throw new RuntimeException(e);
        } finally {
            //释放
            this.release();
        }
    }

记得将之前的事务通知注销

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值