2

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?

Hagai Cibulski
  • 4,421
  • 3
  • 20
  • 23

0 Answers0