Transaction error resolution: Transaction rolled back because it has been marked as rollback-only

Error analysis on Transaction rolled back because it has been marked as rollback-only

Use the transaction to report an error when performing the delete operation. The error message is as follows:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

code analysis

The calling code is as follows: briefly describe the business logic, there is an order unit in the database entity, so when deleting the database, you need to delete the order unit first, and then delete the database after the deletion is successful.

@Override
    public boolean delete(Long id) {
    
    
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(TransactionDefinition.withDefaults());
        int result = 0;
        try {
    
    
        
        	 //-------------业务逻辑开始-------------
            //删除订购单元
            List<EbookCollectionUnitBean> collectionUnitBeans = ebookCollectionUnitMapper.selectList(Wrappers.<EbookCollectionUnitBean>lambdaQuery()
                    .eq(EbookCollectionUnitBean::getEbookCollectionId, id));
            if (CollectionUtils.isNotEmpty(collectionUnitBeans)) {
    
    
                collectionUnitBeans.stream().forEach(x -> eBookCollectionUnitService.delete(x.getId()));
            }
            //删除数据库
            result = ebookCollectionMapper.deleteById(id);
            //-------------业务逻辑结束-------------

            //事务提交
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
    
    
           dataSourceTransactionManager.rollback(transactionStatus);
            e.printStackTrace();
            throw new BusinessException(e.getMessage());
        }
        return result > 0;
    }

In the above business code, call the program to delete the order unit: eBookCollectionUnitService.delete(x.getId()))

    @Override
    public Boolean delete(Long id) {
    
    

        boolean result = false;
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(TransactionDefinition.withDefaults());
        try {
    
    
            EbookCollectionUnitBean ebookCollectionUnitBean = ebookCollectionUnitMapper.selectById(id);
            /**
             * 如果 数字资源采购库 的收录时间修改,则更改所属期刊下的所有文章 标记为馆藏资源
             */
            if (ebookCollectionUnitBean.getPurchaseFlag() == 1) {
    
    
                updateUnitPaperSource(ebookCollectionUnitBean, null);
            }

            result = ebookCollectionUnitMapper.deleteById(id) > 0;

            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
    
    
            log.error("===delete error info", e);
            dataSourceTransactionManager.rollback(transactionStatus);
        }
        return result;
    }

problem analysis

Directly speaking, the code in the second paragraph reported an error when updating the database, causing the transaction to roll back. When
the transaction in the first piece of code is executed, it will be found
dataSourceTransactionManager.commit(transactionStatus);
Transaction rolled back because it has been marked as rollback-only(The transaction is already in the rollback state) Because it is marked as rollback only, it can only execute select queries, and the insert/update/delete operations must be rolled back. At this time, the execution of the transaction commit will inevitably report an error, so it is caught by the catch, and at the
same
dataSourceTransactionManager.commit(transactionStatus);
time There is also transaction rollback code in the catch
dataSourceTransactionManager.rollback(transactionStatus);
, so the second error will be triggered:
Transaction is already completed - do not call commit or rollback more than once per transaction(do not call commit or rollback more than once per transaction)

problem solved

It can be seen that the transaction is rolled back due to an error reported in the second code, modifyBusiness codeThis will resolve the issue. At this time, if the call does not report an error, then the first piece of code can successfully submit the transaction, and the second error report will be resolved accordingly.

Guess you like

Origin blog.csdn.net/qq_29864051/article/details/130259501