我有一个应用程序,我在该应用程序中发送队列消息以获取我的用户对象的referenceNumber。然后等待队列响应,然后再响应REST调用。但是,我必须等待配置的时间才能返回队列响应。
UserManagerImpl
// REST CALL to persist
public User Persist(User user) {
...
...
// Building the message for sending to QUEUE
UserEnvelopeV1_0 userEnvelope =buildUserEnvelope(user);
// This is the place i send the queue message
userQueueClient.send(userEnvelope);
// Update Request time
updateRequestDetails(user.getUserId);
// This is the call i am going retry
boolean userValid = userRetryTemplate.doUserReferenceRetry(userId);
if (!userValid ) {
//remove User Object
throw Exception
}
...
}
// update the request time for reference Number
private void updateRequestDetails(String userId) {
User user = userRepository.findById(userId);
if (user != null) {
user.setRefRequestDateItem(DateHelper.createXMLGregorianCalendar());
userRepository.saveAndFlush(bankAccount);
}
public void updateReference(String userId, String referenceNumber) {
User user = userRepository.findById(userId);
if (user != null) {
user.setReference(referenceNumber);
user.setResponseDate(DateHelper.createXMLGregorianCalendar());
userRepository.saveAndFlush(bankAccount);
}
}
UserQueueClient:
@Component
public class UserQueueClient {
@JmsListener(id = "#{T(java.util.UUID).nameUUIDFromBytes('${in.res}",
destination = "${in.res}", containerFactory = "containerFactory")
public void receive(Message message, UserEnvelopeV1_0 envelope) throws{
try {
String userId = envelope.getHeader().getMessageIdentification().getUserId();
ApplicationInformationStructure applicationInformation = envelope.getBody().getApplicationInformation();
if(CollectionUtils.isNotEmpty(applicationInformation.getApplicationInformationResult())) {
String referenceNumber = applicationInformation.getApplicationInformationResult().getRefNumber();
userManager.updateReference(userId, referenceNumber);
}
} catch (Exception e) {
//
}
}
@Transactional(propagation = Propagation.MANDATORY)
public void send(UserEnvelopeV1_0 sarsSoapEnvelope) throws JMSException {
envelope.setHeader();
Message message = sendToQueue(envelope, requestQueue, responseQueue,
userId);
applicationEventPublisher.publishEvent(new MessageLogEvent("USER_GET_REF_NUMBER", message, MessageType.XML,
requestQueue, MessageDirection.SEND, true, false, new Date(), userId));
}
}
UserRetryTemplate
@Component
public class UserRetryTemplate {
@Value("${retry.max.attempts:5}")
private int maxAttempts;
@Value("${response.waiting.time.in.seconds:60}")
private long maxDelay;
@Autowired
private UserRepository userRepository;
private static final long INITIAL_INTERVAL = 2000L;
public RetryTemplate retryTemplate() {
// Max timeout in milliseconds
long maxTimeout = maxDelay*1000;
//double multiplier = (maxTimeout - INITIAL_INTERVAL)/((maxAttempts-2)*6000);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(maxAttempts);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(maxTimeout/(maxAttempts-1));
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(retryPolicy);
template.setBackOffPolicy(backOffPolicy);
return template;
}
public boolean doUserReferenceRetry(String userId) {
boolean isUserReferenceValid = true;
try {
boolean isValidBankAccount = retryTemplate().execute(context -> {
logger.info("Attempted {} times", context.getRetryCount());
User user = userRepository.findById(userId);
logger.info("User Retry :" + user);
if (bankAccount.getRefResponseDateItem() == null || bankAccount.getReferenceNumber == null) {
logger.info("response not yet received");
throw new IllegalStateException("User Response not yet received");
}
if (bankAccount.getReferenceNumber != null)) {
return true;
}
throw new IllegalStateException("Response not yet received");
});
return isUserReferenceValid ;
} catch (IllegalArgumentException e) {
}
return true;
}
}
因此,我实现了一种逻辑,在该逻辑中,我将发送队列消息并进行Spring重试(针对配置的时间),以检查数据库中的referenceNumber是否已更新。另外,当队列响应返回时,我将使用referenceNumber更新数据库。
但是,当我实现上述逻辑时,spring重试将一直重试直到配置的时间,但是我的Spring应用程序未处理任何响应队列。Spring应用程序是否可以并行运行两个进程。
问题是,如果我删除弹簧重试机制,响应队列正在处理我的响应并使用参考号更新用户记录。
但是当我添加重试逻辑时,响应队列不再处理我的队列。
我发现下划线令人困惑。
“,我将在其中发送队列消息并进行Spring重试(配置的时间)以检查数据库中的referenceNumber是否已更新。此外,当队列响应返回时,我将使用referenceNumber。“
在一行中,您说您正在等待参考号更新,而在另一行中,您说您正在更新数据库。这里的生产者是谁?有两个不同的线程吗?生产者和消费者在这种情况下就是你。
如果要在配置的时间内阻止当前线程您可以考虑使用poll(长超时,TimeUnit单位)方法来阻止队列]
poll(long timeout, TimeUnit unit) – retrieves and removes the head of the queue, waiting up to the specified wait time if necessary for an element to become available. Returns null after a timeout
请编辑问题并提供足够的细节。