上传数据时提示transaction was marked for rollback only; cannot commit错误

在写上传文件,异步解析Excel数据时,老是出现“Transaction was marked for rollback only; cannot commit”错误,卡了很长一段时间。今天终终于于解决,发现是事务嵌套的情况下导致的问题。

最外层Controller调用了procesService的create()方法创建进程:

//创建上传文件进程
procesService.create(file, userId);

create中调用了proxyService的asyncProcessFiles()异步处理上传的数据:

//异步解析上传的Excel文件
proxyService.asyncProcessFiles(process.getId());

asyncProcessFiles中调用了sampleService中的batchImport()执行具体的数据解析动作

sampleService.batchImport(processId);

最初三个方法都加了@Transactional事务控制,发现数据重复时总是提交不成功,于是去掉最里面两层的@Transactional,测试发现还是不行,本意是首先创建上传文件进程,在数据解析成功入库后,上传文件进程的状态置为1,否则状态为0。但在这种情况下,外层create事务正常提交依旧报错,上传进程也会创建失败。于是将create的@Transactional也去掉,每层向上抛出异常(throws),测试成功,问题解决。

原因:
一个事务方法A调用另一个事务方法B时,B如果报错事务就已经是回滚状态了,放回到A之后,A方法继续执行,提交了事务(已经是回滚状态的事务),就报错了 Transaction marked as rollback only。

在spring中,在事务方法中调用多个事务方法时,spring将会把这些事务合二为一。当整个方法中每个子方法没报错时,整个方法执行完才提交事务,如果某个子方法有异常, spring将该事务标志为rollback only。如果这个子方法没有将异常往上整个方法抛出或整个方法未往上抛出(只在调用时catch住了内层异常),那么该异常就不会触发事务进行回滚,事务就会在整个方法执行完后提交,这时就会造成Transaction rolled back because it has been marked as rollback-only异常。如果我们往上抛了该异常,spring就会获取异常,并执行回滚。

在这里插入图片描述
参考https://blog.csdn.net/weixin_39407754/article/details/105222531

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值