发生违反约束的异常后,如何继续处理



我们在Java-Spring Boot服务中有一个Kafka使用者,它在多个集群中有多个实例(所有实例都具有相同的使用者组id(。使用者将数据保存到数据库(SQL Server(中。

在保存到数据库之前,代码会检查ItemSet表中是否存在记录。有效负载中的实际数据保存在子表ItemValue中,而不是父表ItemSet中。关系数据表层次结构是按ItemSet->ItemName->ItemValueItemSet表有一个unique constraint用于部门id、季节组合,以防止多次重复添加。

我需要在捕捉到这个异常后进行一些处理,以确保传入的数据仍然保存在现有的ItemSet下,不会丢失。我使用的是Spring Data JPA,一旦我发现异常并尝试检索现有记录,我就会得到:

org.hibernate.AssertionFailure:ItemSet条目中的id为null(发生异常后不要刷新会话(。

catch块中的getItemSet()爆炸。

克服这些比赛条件的最佳方法是什么?

ItemSet savedItemSet = null;
try
{
String seasonName = itemSet.getSeasonName();
Long seasonYear = itemSet.getSeasonYear();
Long departmentId = itemSet.getDepartment().getId();
List<ItemSet> itemSets = attributeSetRepository.findBySeasonNameAndSeasonYearAndDepartmentId(
seasonName, seasonYear, departmentId);
LOGGER.info("Found {} item sets corresponding to season name : {}, season year : {}, "
+ "department id : {}", itemSets.size(), seasonName, seasonYear, departmentId);
if(CollectionUtils.isEmpty(itemSets)) {
savedItemSet = itemSetRepository.save(itemSet);
}
else {
return new CreatedItemSet(itemSets.get(0).getId());
}
}
catch(PersistenceException | DataIntegrityViolationException e) 
{
LOGGER.error("An exception occurred while saving itemSet set", e);
if (e.getCause() instanceof ConstraintViolationException) 
{
String seasonName = itemSet.getSeasonName();
Long seasonYear = itemSet.getSeasonYear();
Long deptId = itemSet.getDepartment().getId();
LOGGER.info("A duplicate item set found in the database corresponding "
+ "to season name : {}, season year : {} and department : {}",
seasonName, seasonYear, deptId);

ExistingItemSet existingItemSet = getItemSet(seasonName, 
seasonYear, deptId);
if(existingItemSet == null) {
LOGGER.info("No item set found");
return null;
}
return new CreatedItemSet(existingItemSet.getId());
}
}

你不能"继续";。事务被标记为回滚,并且在发生约束冲突后,持久性上下文不可用。

您可以通过在持久化/更新之前检查DB是否包含条目来避免约束冲突,也可以在发生约束冲突时在单独的事务中运行其余代码。

相关内容

  • 没有找到相关文章

最新更新