博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly
阅读量:6509 次
发布时间:2019-06-24

本文共 2337 字,大约阅读时间需要 7 分钟。

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

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");}@TransactionalmethodC() {    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也是这样的。而我只是在外面捕捉了这个异常,所以发生的这样的问题。

 

转载于:https://www.cnblogs.com/fashflying/p/5669228.html

你可能感兴趣的文章
今年以来硅晶圆涨幅约达40%
查看>>
构建智能的新一代网络——专访Mellanox市场部副总裁 Gilad Shainer
查看>>
《数字视频和高清:算法和接口》一导读
查看>>
《中国人工智能学会通讯》——6.6 实体消歧技术研究
查看>>
如何在Windows查看端口占用情况及查杀进程
查看>>
云存储应用Upthere获7700万美元股权债务融资
查看>>
国家互联网应急中心何世平博士主题演讲
查看>>
洗茶,你误会了多少年?
查看>>
贵阳高新区力争打造“千亿级大数据园区”
查看>>
安防众筹不止于卖产品 思维拓展刺激消费
查看>>
OpenSSH曝高危漏洞 会泄露私钥
查看>>
艾特网能获2016APCA用户满意品牌大奖
查看>>
《CCNP TSHOOT 300-135学习指南》——第2章 结构化故障检测与排除进程
查看>>
《Java EE 7精粹》—— 2.5 非阻塞I/O
查看>>
《Python数据科学实践指南》一2.2 字符串
查看>>
《R数据可视化手册》——1.1 安装包
查看>>
《iOS创意程序设计家》——导读
查看>>
spring-aop
查看>>
android RecycleView Adapter简单封装
查看>>
PgSQL · 案例分享 · 递归收敛优化
查看>>