zoukankan      html  css  js  c++  java
  • 解决Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly

    项目测试发生问题,方法正常结束,但是报了

    Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)

    错误,问什么不能提交呢?

    经过查找发现了这么一段话

    I finally understood the problem:
    
    methodA() {
        methodB()
    }
    
    @Transactional(noRollbackFor = Exception.class)
    methodB() {
        ...
        try {
            methodC()
        } catch (...) {...}
        log("OK");
    }
    
    @Transactional
    methodC() {
        throw new ...();
    }
    What happens is that even though the methodB has the right annotation, the methodC does not. When the exception is thrown, the second @Transactional marks the first transaction as Rollback only anyway.

    原来,在一个transactional中如果有另一transaction发生了异常,即使你捕捉了这个异常,那么Transaction也会被定义成RollbackOnly,这也正是事务管理的原则,可是我的系统哪里出异常了呢?

    原来,spring jpa JpaRepository的实现方法中用ID删除的源码是这样的

    @Transactional
        public void delete(ID id) {
    
            Assert.notNull(id, ID_MUST_NOT_BE_NULL);
    
            T entity = findOne(id);
    
            if (entity == null) {
                throw new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!",
                        entityInformation.getJavaType(), id), 1);
            }
    
            delete(entity);
        }

    他是这样实现的,先查找这个ID的对象看是否存在如果不存在则直接抛出一个非检查型异常,就不再执行delete操作。这和我平常习惯认为的不太一样,一般我习惯删除没有的记录不会报错,执行sql也是这样的。而我只是在外面捕捉了这个异常,所以发生的这样的问题。

  • 相关阅读:
    块元素&行内元素
    semantic ui要装什么才能使用
    float属性
    CSS 选择器
    px,em和rem
    CSS各类布局
    一个 / 引起想骂他事件
    使用fastjson 获取json字符串中的数组,再转化为java集合对象
    计算面试题
    Dubbo(二) 一次惨痛的流血事故
  • 原文地址:https://www.cnblogs.com/fashflying/p/5669228.html
Copyright © 2011-2022 走看看