我正在尝试保存一些SQL事务。我在ESB路由的上下文中,从SQL源传输到SQL目标,SQL事务的顺序不能保证,因此您可以在对象插入之前进行SQL更新。
由于架构原因,我将这些SQL事务1000个1000个地保存(我正在使用消息队列)。因此,其中一些可能会失败,并且我会重新路由它们以重试或拒绝它们。为了提高效率,我愿意改进旧系统,在该系统中,如果1000个失败,则逐个保存1个,通过递归实现二分法(如果保存失败,则拆分列表并重试),我还通过另一个列表(objectsNo)跟踪我的对象的属性,以进行进一步操作。
但是,在第一次递归中调用objectsList.size()时,我遇到了ConcurrentModificationException。如何避免它?我也很开放,并且非常感谢任何解决方案,这些解决方案提供了除了二分法以外的提高效率的方法(并且将绕过我的问题)。
我尝试理解,但不应该有任何错误。即使我使用递归,它仍然是单线程的。我认为问题可能出在Hibernate上(一些来自失败的保存的请求可能会留在缓存中,并锁定修改),但问题在于size,它在原始列表的子列表上。
由于架构原因,我将这些SQL事务1000个1000个地保存(我正在使用消息队列)。因此,其中一些可能会失败,并且我会重新路由它们以重试或拒绝它们。为了提高效率,我愿意改进旧系统,在该系统中,如果1000个失败,则逐个保存1个,通过递归实现二分法(如果保存失败,则拆分列表并重试),我还通过另一个列表(objectsNo)跟踪我的对象的属性,以进行进一步操作。
但是,在第一次递归中调用objectsList.size()时,我遇到了ConcurrentModificationException。如何避免它?我也很开放,并且非常感谢任何解决方案,这些解决方案提供了除了二分法以外的提高效率的方法(并且将绕过我的问题)。
我尝试理解,但不应该有任何错误。即使我使用递归,它仍然是单线程的。我认为问题可能出在Hibernate上(一些来自失败的保存的请求可能会留在缓存中,并锁定修改),但问题在于size,它在原始列表的子列表上。
private List<String> saveObjectWithDichotomie(List<Object> objects,
List<String> objectsNo,
Exchange exchange) throws JsonProcessingException {
try {
objectRepository.save(objects);
return objectsNo;
} catch (DataIntegrityViolationException e) {
if (objects.size() == 1) {
objectsNo.clear();
errorProcessor.sendErrorToRejets(objects.get(0), exchange, e);
return objectsNo;
} else {
List<Object> objectsFirstHalf = objects.subList(0, objects.size()/2);
List<Object> objectsSecondHalf = objects.subList(objects.size()/2, objects.size());
List<String> objectsNoFirstHalf = objectsNo.subList(0, objectsNo.size()/2);
List<String> objectsNoSecondHalf = objectsNo.subList(objectsNo.size()/2, objectsNo.size());
objectsNo.clear();
objectsNo.addAll(
saveObjectWithDichotomie(objects, objectsNoFirstHalf, exchange)
);
objectsNo.addAll(
saveObjectWithDichotomie(objects, objectsNoSecondHalf, exchange)
);
return objectsNo;
}
}
}
sublist
有关,它被记录为由此列表支持,因此一个列表中的更改会反映到另一个列表中,反之亦然。我认为您应该创建一个新的List
,例如List<Object> objectsFirstHalf = new ArrayList<>(objects.subList(0, objects.size()/2));
。 - Eugene