解决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也是这样的。而我只是在外面捕捉了这个异常,所以发生的这样的问题。

时间: 2025-01-18 01:55:12

解决Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly的相关文章

spring boot配置spring-data-jpa的时候报错CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.NoSuchMethodError

F:\java\jdk8\jdk1.8.0_211\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\软件\IntelliJ IDEA 2019.2.2\lib\idea_rt.jar=7513:D:\软件\IntelliJ IDEA 2019.2.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\软件\IntelliJ IDEA 2019.2.2

“Transaction rolled back because it has been marked as rollback-only”

spring的声明事务提供了强大功能,让我们把业务关注和非业务关注的东西又分离开了.好东西的使用,总是需要有代价的.使用声明事务的时候,一 个不小心经常会碰到“Transaction rolled back because it has been marked as rollback-only”这个异常.有时候又常常会纳闷,"我已经try-catch了,为什么还这样呢?" Xml代码   <!-- 0 placeHolder --> <bean  class=&quo

Spring事务嵌套抛异常org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

在业务接口中,一个方法嵌套了另外一个方法,2个方法上都加了@Transactional事务注解. 业务接口: @Service public class TransactionalTestServiceImpl implements TransactionalTestService { @Autowired private TransactionalTestHandle transactionalTestHandle; @Override @Transactional public void f

Could not commit JPA transaction; nested exception is javax.persistence.RollbackException

原因:同一service方法里多次save导致,save过一次,事务已经提交了,如果再次save,则事务已经变为回滚状态,已经不能再次提交事务了.

使用JPA保存对象时报nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly错误

刚开始以为是数据库中的表有问题,主键的字段不能为空,结果给它赋值了还是不行,再一看数据库中有些非空的字段没有设值,又改了 一下表的结构,允许为空,结果还是报错.再一想是不是因为实体类实现了序列化的原因

Could not open JPA EntityManager for transaction; nested exception is java.lang.NullPointerException

1 <persistence-unit name="WebofficeOne" transaction-type="JTA "> 改为 1 <persistence-unit name="WebofficeOne" transaction-type="RESOURCE_LOCAL"> JTA 在jee环境下运行 RESOURCE_LOCAL在jse环境下使用

解决Springboot项目中jpa扫描不到实体的问题

在一些情况下Springboot项目中jpa扫描不到实体.比如默认扫描不到引用的其他项目中定义的实体.导致无法自动创建表. 解决方法,在Application中自定义实体扫描的包 @EntityScan(basePackages = {"com.aaa"}) @SpringBootApplication @EnableDiscoveryClient @ComponentScan(basePackages = {"com.aaa.*"}) @EntityScan(ba

解决github提交commit,contributions不统计显示绿色的问题

最近使用GitHub Desktop时,发现自己好多次的commits都没有被记录在Contributions中,但是点开项目详情里面可以看到自己的commit确实上传成功了,所以就忧伤了,为什么没有绿呢? 然后去了解了下Contributions的规则,发现只会记录以下几种: Issues 和 pull requests 这个操作是在一年之内 这个操作是针对一个独立的仓库,不能是fork Commits 当你的commits满足以下条件时,它才会被展示出来: 一年之内提交的commits co

Review: the foundation of the transaction、Transaction characteristics in Spring

1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败). 2.事务特性: 事务特性分为四个:原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持续性(Durability)简称ACID. 原子性(Atomicity):事务是数据库逻辑工作单元,事务中包含的操作要么都执行成功,要么都执行失败. 一致性(Consistency):事务执行的结果必须是使数据库数据