2

I need to perform the batch operation with a Pessimistic lock so that no other can read or write this row during this operation. But I want to increment the page number after every batch so that if the transaction failed or instance died, I will continue from the last page. But with the below code, it is not updating the page until all batches are completed so when restarting the job, it's processing from page=0.

@Transactional
public void process(long id) {
    Entity entity = repo.findById(id);
    processBatch(entity);
}

void processBatch(Entity entity) {
    int totalPages = otherMicroService.getTotalPages(id);
    int lastPage = entity.getPage();
    for(int page=lastPage; i<totalPages; i++) {
        doOperation();
        entity.setPage(page);
        repo.save(entity);
    }
}


@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Entity> findById(int id);

Is there a way to update the page after every batch with PESSIMISTIC_WRITE enabled?

Thanks in Advance.

Forece85
  • 428
  • 1
  • 6
  • 22

1 Answers1

1

I'd add @Transactional(propagation = Propagation.REQUIRES_NEW) to the processBatch so the data will be committed at every iteration (btw, save and saveAndFlush will work the same in this case).

Be aware that after adding this annotation the processBatch method needs to be moved to the separate bean (or bean's self-injection should be made) in order to make Spring AOP work correctly.

amseager
  • 5,795
  • 4
  • 24
  • 47
  • You mean @Transactional on process() and @Transactional(propagation = Propagation.REQUIRES_NEW) on processsBatch(), both annotations? Would not @Lock(LockModeType.PESSIMISTIC_WRITE) blocks writes for new transactions then? – Forece85 Dec 14 '21 at 21:37
  • Tried. Still updates not happening. I believe its because of lock: @Lock(LockModeType.PESSIMISTIC_WRITE). Any alternative way to tackle this! – Forece85 Dec 14 '21 at 22:21
  • Sorry, I meant extracting the inner code from "for" statement to the separate bean with the "REQUIRES_NEW" method. Also, you'd probably need to set sth like `@Transaction(noRollbackFor=Exception.class)` for the outer method to disable rollbacks for already processed batches – amseager Dec 14 '21 at 22:37
  • Thankyou. But it's still the same. I could see updated value during the job or even after killing the job in between. – Forece85 Dec 14 '21 at 22:56