我接手了一个系统,其中存在一个相当奇怪的错误,可能每六个月才会出现一次,即应用程序突然丢失对数据库数据的跟踪。
该系统具有两台服务器的冗余,它们被安排在同一时间运行相同的功能。它们都获得相同的输入数据到函数,并且它们都与同一个PostgreSQL数据库通信,但是这两台机器的行为不同。
正在执行的函数调用数据库并检查是否存在指定ID的行作为输入参数提供,并且如果存在,则执行
问题在于一台服务器执行
以下是从数据库获取的代码:
该系统具有两台服务器的冗余,它们被安排在同一时间运行相同的功能。它们都获得相同的输入数据到函数,并且它们都与同一个PostgreSQL数据库通信,但是这两台机器的行为不同。
正在执行的函数调用数据库并检查是否存在指定ID的行作为输入参数提供,并且如果存在,则执行
A()
,否则执行B()
。问题在于一台服务器执行
A()
,而另一台执行B()
。 我已经搜索了所有地方,没有代码编写到此表中或从中删除。 因此,在所有合理性范围内,我认为它们应该执行相同的代码。以下是从数据库获取的代码:
@PersistenceContext(unitName = "backend-persistence")
private EntityManager em;
public Optional<OfferEntity> getOfferFromOfferId(final long offerId, final String countryAlias, final String langauageAlias) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<OfferEntity> cq = cb.createQuery(OfferEntity.class);
Root<OfferEntity> from = cq.from(OfferEntity.class);
cq.select(from);
cq.where(cb.and(cb.equal(from.get(OfferEntity_.offerId), offerId),
cb.equal(from.get(OfferEntity_.country), countryAlias),
cb.equal(from.get(OfferEntity_.language), langauageAlias)));
try {
return Optional.of(em.createQuery(cq).getSingleResult());
} catch (NoResultException nre) {
return Optional.empty();
}
}
我从其中一台服务器得到了一个空的可选项,但是没有从另一个服务器得到。
因此,简单来说,我是否误解了NoResultException,在什么具体情况下可以抛出它?除了查询中没有匹配行之外。
getSingleResult
方法返回的缺失结果视为异常情况,这是因为它本来就应该与必然只产生一个结果的查询(例如聚合查询)一起使用。对于“根据我的业务逻辑可能永远不会有多个结果”的查询,getSingleResult
方法并不是一个好的选择,你应该使用getResultList
方法。 - crizzis