【发布时间】: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