The main thread deletes the sub-thread and can still find the data

Situation: I did a delete operation in the main thread, but it can still be found in the child thread. I used a transaction and set the propagation level of the transaction, but it still didn't work. But by asking Daniel, I found the following methods:

1. Method 1: Use for update in the query statement of the child thread. (Not tried)
for update is a row-level lock, also known as an exclusive lock. Once a user imposes a row-level lock on a row, the user can query or update the locked data row, and other users only Can query but cannot update locked data rows. If other users want to update the data rows in the table, they must also apply row-level locks to the table. Even if multiple users use shared updates to a table, two transactions are not allowed to update a table at the same time. When the table is actually updated, the table is locked exclusively until the transaction is committed or restored. Row locks are always exclusive mode locks.

2. Method 2: Submit directly after the main thread is deleted.


```java
 @Transactional
    public void onlineConfirmImport(MultipartFile file, Integer agencyAgreementType, String importYear) {
    
    
        String errorImport = "导入模板不正确";
        // 获取上传数据
        List<OnlineConfirmImportVO> loadExcelData = loadExcelData(file, agencyAgreementType);
        //手动获取事务状态
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        //删除旧的年份数据
        try {
    
    
            //通过agencyAgreementType importYear 查到对应的线上确认数据
            OnlineConfirmSearchDTO onlineConfirmSearchDTO = new OnlineConfirmSearchDTO();
            onlineConfirmSearchDTO.setAgencyAgreementType(agencyAgreementType);
            onlineConfirmSearchDTO.setImportYear(importYear);
            List<OnlineConfirm> yearList = onlineConfirmDao.getList(onlineConfirmSearchDTO);
            List<Long> ids = new ArrayList<>();
            List<String> agencyAgreementCodes = new ArrayList<>();
            yearList.forEach(onlineConfirm -> {
    
    
                ids.add(onlineConfirm.getId());
                agencyAgreementCodes.add(onlineConfirm.getAgencyAgreementCode());
            });
            if(!ids.isEmpty()) {
    
    
                onlineConfirmDao.deleteByIds(ids);
            }
            if (!agencyAgreementCodes.isEmpty()) {
    
    
                onlineManualDao.deleteByAgencyAgreementCodes(agencyAgreementCodes);
            }
            transactionManager.commit(transactionStatus);
        }catch (Exception e){
    
    
            transactionManager.rollback(transactionStatus);
            throw  new BusinessException("导入失败,数据异常");
        }

        //创建子线程去做操作...
     
    }

3. Optimization of method two.
In method 2, we submit the transaction directly after deleting, but we may have an exception in the sub-thread or subsequent business. It is wrong to delete it for him.
So when we delete, we can not do physical deletion first, we first make a logical deletion for him, and use ThreadLocal to save the deleted data. Use try-catch-finally , if there is an exception, we manually update the data in the catch to restore it; if there is no exception, we will take out the data in ThreadLocal in finally, and delete their real logic.

Guess you like

Origin blog.csdn.net/weixin_45933454/article/details/127068104