Открыть новую транзакцию для каждого элемента в списке с помощью Spting MVC - PullRequest
0 голосов
/ 27 апреля 2018

Я не могу открыть новую транзакцию для каждого элемента при итерации списка с помощью 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);
    }
}

}

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Я решил проблему, добавив 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;
}
0 голосов
/ 29 апреля 2018

UpdateIntent уже находится в другом классе: IntentImportExportService, который внедряется в вызывающую функцию как ресурс, поэтому проблема не в этом ... Вы уверены, что выбранный менеджер транзакций поддерживает вложенные транзакции?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...