【问题标题】:Open new transaction for every item in list with Spting MVC使用 Spring MVC 为列表中的每个项目打开新事务
【发布时间】:2018-10-08 16:36:18
【问题描述】:

使用 Spring Boot 迭代列表时,我无法为每个项目打开新事务。我只想回滚失败的项目并继续列表中的其余项目。一个事务中有多个提交,如果任何失败都必须回滚。 我的服务代码如下。

@Service("intentExportImportService")
public class IntentExportImportServiceImpl implements IntentExportImportService {
@Resource(name = "intentExportImportService")
private IntentExportImportService intentExportImportService;

 public  Map<String, Integer> importIntents(ExportImportData exportImportData,boolean overwrite) throws DataAccessLayerException {

    Map<String, Integer> statiscisMap= createOrUpdateIntent(exportImportData,overwrite);
    return statiscisMap;
}

private Map<String, Integer> createOrUpdateIntent(ExportImportData exportImportData,boolean overwrite)throws DataAccessLayerException {
    List<Intent> intentsList = exportImportData.getIntents();
    Map<String,Entity> entityMap = getEntityMap(exportImportData.getEntityList());
    Map<String,Api> apiMap = getApiMap(exportImportData.getApiList());
    Map<String,Integer> statisticsMap = new HashMap<>();
    Long domainId = ExcelUtil.getDomainId(exportImportData.getDomainName());
    for(Intent intent : intentsList) {
        Intent existingIntent =  intentExists(intent.getIntentNm());
       if(existingIntent != null){
           startUpdateIntent(intent,existingIntent,entityMap,apiMap,overwrite,statisticsMap,domainId);
       }else{
           startCreateIntent(intent,entityMap,apiMap,overwrite,statisticsMap,domainId);
       }
    }
    return statisticsMap;
}

@Transactional
public void startUpdateIntent(Intent intent, Intent existingIntent, Map<String, Entity> entityMap, Map<String, Api> apiMap, boolean overwrite, Map<String, Integer> statisticsMap, Long domainId) {

    try {
        intentExportImportService.updateIntent(intent, existingIntent, entityMap, apiMap, overwrite, statisticsMap,domainId);
    }catch (Exception e)
    {
        updateStatisticsMap(FAILED,statisticsMap);
        LOGGER.error("Error Importing Intents to update and hence rolling back intent: "+intent.getIntentNm());

    }
}

@Transactional(value = "dataTxManager", propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED, rollbackFor = {
    DuplicateException.class, DataAccessException.class,DataAccessLayerException.class, SQLTimeoutException.class, SQLException.class,Exception.class})
public void updateIntent(Intent intent, Intent existingIntent, Map<String, Entity> entityMap, Map<String, Api> apiMap, boolean overwrite, Map<String, Integer> statisticsMap,Long domainId) throws DataAccessLayerException {

    if(!overwrite){
        LOGGER.info("Not overwriting the Intent: "+intent.getIntentNm()+" as it already exist and overwrite is false");
        throw new DataAccessLayerException(CommonConstants.IMPORT_FAILURE_ERROR_CODE,"rolling back intent importing: "+intent.getIntentNm());
    }
    manageEntitiesAndApis(intent, entityMap, apiMap, overwrite,domainId);
    Long intentId = updateImportedIntent(intent,existingIntent);
    if(intentId != null) {
        updateStatisticsMap(UPDATED, statisticsMap);
    }
}

}

【问题讨论】:

  • 参见此处关于 self 方法调用的讨论。 stackoverflow.com/q/3423972/1356423 尝试,将 updateIntent(...) 移动到单独的类或实现给定的其他解决方案之一。

标签: spring-mvc spring-transactions


【解决方案1】:

UpdateIntent 已经在另一个类中:IntentImportExportService 作为资源注入调用者,所以问题不存在...... 您确定所选的事务管理器支持嵌套事务吗?

【讨论】:

    【解决方案2】:

    我通过在 for 循环中添加 try catch 解决了这个问题,如下所示

     @Transactional
    public Map<String, Integer> createOrUpdateIntent(ExportImportData exportImportData,boolean overwrite) {
        List<Intent> intentsList = exportImportData.getIntents();
        Map<String,Entity> entityMap = getEntityMap(exportImportData.getEntityList());
        Map<String,Api> apiMap = getApiMap(exportImportData.getApiList());
        Map<String,Integer> statisticsMap = new HashMap<>();
        Long domainId = ExcelUtil.getDomainId(exportImportData.getDomainName());
        for(Intent intent : intentsList) {
            try {
                Intent existingIntent = intentExists(intent.getIntentNm());
                if (existingIntent != null) {
                    intentExportImportService.updateIntent(intent, existingIntent, entityMap, apiMap, overwrite, statisticsMap, domainId);
                } else {
                    intentExportImportService.createIntent(intent, entityMap, apiMap, overwrite, statisticsMap, domainId);
                }
            } catch (DataAccessLayerException e) {
                updateStatisticsMap(FAILED,statisticsMap);
                LOGGER.error("Error Importing Intents to update and hence rolling back intent: "+intent.getIntentNm());
            }
        }
        return statisticsMap;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多