我有一个要求,我必须在一个表中插入记录并在另一个表中更新记录。
在插入和更新之前,我必须完成100条记录。 但是,如果任何记录由于插入或更新中的任何错误而失败,则仅应回滚该记录而不是其他记录。这意味着如果有100条记录并且60条获得成功,而61条由于任何错误而失败,则仅应回滚61条记录其他60条记录。
我正在使用Spring boot JPA和@Transactional注释。但是如果将此注释放在我的方法开始处,那么如果发生任何错误,它将回滚所有记录。
我在下面附上我的代码。请提出如何实现此目的。 在下面的代码中,我有persistentRecord()方法,其中包含我所有的插入和更新代码。我没有使用@Transactional注释来标记此方法,而在下面的方法中使用@Transactional注释进行了注释
logger.debug("insertSalesTargetData method called of service class");
String userid = (String) webSession.getAttribute("username");
logger.debug("Userid :" + userid);
HashMap<String, String> persistRecordStatus = new HashMap<String, String>();
Query qCountCheck = em.createNativeQuery(QueryConstant.CHECK_SALES_TARGET_DATA_QUERY);
List<Object> existingRecordList = null;
persistRecordStatus.put("TOTAL_RECORD", String.valueOf(xlsRowslist.size()));
int failedRecordCount = 0;
int successRecordCount = 0;
for (int i = 0; i < xlsRowslist.size(); i++) {
ArrayList rowList = xlsRowslist.get(i);
// try {
double weekNoDouble = Double.parseDouble((String) rowList.get(0));// Week No
String fromDate = (String) rowList.get(1);// fromDate
String toDate = (String) rowList.get(2);// toDate
double catCodeDouble = Double.parseDouble((String) rowList.get(3));// catCode
int catCode = (int) catCodeDouble;
int weekNo = (int) weekNoDouble;
String target = (String) rowList.get(4);// target
String salesGoalId = fromDate + toDate + catCode;
salesGoalId = salesGoalId.replace("-", "");
// Check if the sales goal id already exist in the database or not
qCountCheck.setParameter(1, salesGoalId);// SALES_GOAL_ID
existingRecordList = qCountCheck.getResultList();
logger.debug("Count List Size " + existingRecordList.size());
if (existingRecordList != null && existingRecordList.size() > 0) {
if (existingRecordList.get(0) != null) {
BigDecimal row = (BigDecimal) existingRecordList.get(0);
// try {
logger.debug("Persisting record no " + i);
persistRecord(row, salesGoalId, target, fromDate, toDate, userid, catCode, weekNo);
logger.debug("Record no " + i + " persisted");
persistRecordStatus.put("SUCCESS_RECORD", String.valueOf(successRecordCount++));
/*
* } catch (Exception e) { persistRecordStatus.put("FAILED_RECORD",
* String.valueOf(failedRecordCount++)); }
*/
}
} else {
persistRecordStatus.put("FAILED_RECORD",String.valueOf(failedRecordCount++));
}
/*
* } catch (Exception e) { logger.debug("Exception in processing record no " + i
* + " " + e.toString()); persistRecordStatus.put("FAILED_RECORD",
* String.valueOf(failedRecordCount++)); }
*/
}
return persistRecordStatus;
}
答案 0 :(得分:1)
您要进行某种批量更新吗?
在批处理中,您将所有涉及的东西(例如输入记录,错误代码等)放在错误存储库中,以供某些用户随后查看,以处理“失败”。然后您将其与所有“成功”更新一起提交。
或者,将每个插入/更新对放入自己的事务中。 (并且仍然可以选择,如果您的DBMS /事务框架支持保存点,则在每个插入/更新对之后获取一个保存点,并在失败时回滚到最后一个保存点,然后提交(并找出一种不会丢失其余40个未处理条目的方法)您的输入)。无论哪种情况,如果遇到性能问题,请不要抱怨。
在事务批处理中,这两种方式都没有。