I'm writing a consumer that should process data written by a producer. Once the producer is finished writing, the consumer should start processing the data belonging to a specific producerExecutionId. I defined the ConsumerExecution entity to rep the consumer's processing.
The problem is that the consumer is actually running on multiple instances, and I need only one inctance to process each producer execution output.
The code below fails in synchonizing between the consumer instances:
@Transactional
public ConsumerExecution initiateConsumerExecutionIfNeeded(String producerExecutionId) {
consumerExecution lastConsumerExecution = consumerExecutionRepository.findTopByOrderByIdDesc();
if (lastConsumerExecution != null && producerExecutionId.equals(lastConsumerExecution.getProducerExecutionId())) {
return null;
}
consumerExecution consumerExecution = new ConsumerExecution(producerExecutionId);
consumerExecutionRepository.save(consumerExecution);
return consumerExecution;
}
Adding @Transactional isn't suffucient since it won't prevent two instances from succesfully creating a ConsumerExecution and saving it.
It seems I need some way to lock the entire table, but @Lock seems unable to provide this functionality.
Maybe I should somehow add to findTopByOrderByIdDesc something like: WITH (TABLOCK, HOLDLOCK) as in here?