2

I am using oracleDB and elasticsearch for persistence and if anything goes wrong in that method, it throws a custom exception. Now I need to rollback from DB if any thing fails in elastic also.

I have already added @transactional annotation on service classes. And everything I found on web.

@Transactional(rollbackOn = BaseException.class)
public void transaction(ab ab, a a) {
    persistenceService.save(a);
    persistenceService.updateSignalCountDb(a.abc(), a.bcd(), ab);
    elasticService.saveSignal(a);

    try {
        elasticService.updateSignalCountElastic(a);
    } catch (Exception e) {
        throw new BaseException(ErrorCodes.FAILED_ELASTIC_SEARCH_UPDATE, e);
    }
}

persistenceService.save() method saves in db. persistenceService.updateSignalCountDb() method update another table in db. elasticService.saveSignal() method saves in elastic. throws base exception in case of failure. elasticService.updateSignalCountElastic() method update another index in elastic. It also calls elasticService.delete() method to delete anything saved in elastic in case of failure and throws a base exception.

I expected this would work in case of any failure in the entire method. But if anything fails on elastic, i get a base exception but my data from oracle db doesn't rollback.

Fábio Nascimento
  • 2,644
  • 1
  • 21
  • 27
  • Check whether AUTO_COMMIT is set to false in data source configuration. Have a look at https://stackoverflow.com/questions/7872773/annotation-transactional-how-to-rollback – Devilluminati Jul 09 '19 at 08:35

2 Answers2

0

At first glance it looks like you are doing everything right. But before you search for the reason why it doesn't work, small change in your code would prevent the problem from occurring in the first place:

  @Transactional(rollbackOn = BaseException.class)
  public void transaction(ab ab, a a){
    try {
      elasticService.saveSignal(a);
      elasticService.updateSignalCountElastic(a);
      persistenceService.save(a);
      persistenceService.updateSignalCountDb(a.abc(), a.bcd(), ab);
    }catch (Exception e){
      throw new BaseException(ErrorCodes.FAILED_ELASTIC_SEARCH_UPDATE, e);
    }
  }

In this case your exception will occur before you even save in DB and you won't have a problem

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
0
  1. If you are using Spring @Transactional, I researched there is only rollbackFor option but not rollbackOn(I'm not sure this), like this: @Transactional(rollbackFor = BaseException.class).

  2. Make sure Transactional is enabled in spring configuration: @EnableTransactionManagement

  3. In your case, only BaseException would trigger rollback, other Exception would not.

liuchu
  • 60
  • 10
  • ```rollbackon``` is used in case I am using ```@Transactional``` of javax. anyways I have started using spring ```@Transactional``` with ```@EnableTransactionManagement``` in spring configuration and I am still getting same results. – Ashish Mittal Jul 09 '19 at 10:06
  • Can you try `@Transactional(rollbackFor = Exception.class)` to see if rollback could be triggered? – liuchu Jul 09 '19 at 11:48
  • I tried that and it doesn't work. however, I was able to recognize the issue and it resolved. – Ashish Mittal Jul 10 '19 at 05:31
  • there was a silly mistake. This method was into a class that was not handled by spring. I just changed its class and get its bean into old class, it started working. – Ashish Mittal Jul 10 '19 at 05:36