我有一个从guava生成listenableFutures的线程池。在任务失败时,我使用两种方法在DB中写入。
第一种方法写入包含各种信息的条目,第二种方法用条目Datetime
和值更新该条目。
public void onFailure(Throwable thrown) {
//This is the Guava callback function in case of failure
if (retransmitPolicyFilter.isRetransmittable(thrown, event)) {
try {
queue.putLast(event);
LOGGER.debug("Adding event [{}] last. It failed initially due to [{}]", event, thrown.getMessage());
} catch (InterruptedException e) {
LOGGER.error("Error {}", e.getMessage());
LOGGER.debug("Error {}", e);
}
} else {
try {
EventLog eventLog = eventLoggingService.logFailedEvent(event, name, thrown);
if (thrown instanceof ResponseTimeoutException) {
LOGGER.error("Error {}", thrown.getMessage());
LOGGER.debug("Error {}", thrown);
LOGGER.warn("Received a Response Timeout Exception error for event [{}] and I will not retry it", event);
} else {
LOGGER.debug("Error sending event [{}]. Logging event with sid [{}]", event, eventLog.getSid(), thrown);
eventLog = eventLoggingService.logOutcomeForEventLog(eventLog.getSid(), "REJECTED");
eventService.forwardEventOutcome("REJECTED", eventLog);
}
} catch (Exception e) {
LOGGER.error("Error handling failure of event [{}]. {}", event, e.getMessage());
LOGGER.debug("{}", e);
}
}
执行数据库插入和更新的两种方法是:
@Override
@Transactional(propagation = Propagation.REQUIRED)
public EventLog logFailedEvent(final Event event, final String name, final Throwable thrown) {
try {
final EventLog om = prepareEventLog(event, name, null);
int code = -1;
if (thrown instanceof TimeoutResponseException) {
code = ((NegativeResponseException) thrown).getCommandStatus();
}
om.setStatus(MessageDeliveryStatusEnum.FAILED.getProperty() + " " + code);
return eventLogRepository.save(om);
} catch (Exception e) {
LOGGER.error("Error saving failed event [{}] for name [{}]. {}", event.toString(), name, e.getMessage());
LOGGER.debug("{}", e);
return null;
}
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public EventLog logOutcomeForEventLog(final long eventId, final String outcomeValue) {
try {
final EventLog o = eventLogRepository.findOne(eventId);
o.setOutcomeReceiveDate(LocalDateTime.now(Clock.systemUTC()));
o.setOutcomeValue(outcomeValue);
return eventLogRepository.save(o);
} catch (Exception e) {
LOGGER.error("Error saving outcome for id [{}] and value [{}]. {}", eventId, outcomeValue,
e.getMessage());
LOGGER.debug("{}", e);
return null;
}
}
大多数事件都失败,因此这段代码每分钟执行数千次,数据库中有数百万条记录。
上述代码生成具有outcome_receive_date
和outcome_value
,
除外有时只有eventLoggingService.logFailedEvent(event,name, thrown)
方法似乎正在执行
而
eventLoggingService.logOutcomeForEventLog(eventLog.getSid(), "REJECTED");
未使用最后两个值(结果通知日期时间和值)更新条目。 没有记录错误,但正如您从上面所看到的,我正在为此做好准备。
我真的很茫然。