简体   繁体   中英

@Transactional annotation doesn't work for method

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.

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

  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM