Home > database >  How to rollback transaction from service class?
How to rollback transaction from service class?

Time:10-28

I am trying to rollback for some condition by throwing exception. But i can not find proper way to do this. Here is my service class

@Service
public class UserManager implements IUserManager {

    private final IBasicEM basicEM;

    public ApplicantInfoManager(IBasicEM basicEM) {
        this.basicEM = basicEM;
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public boolean purgeUser(Long id) throws Exception {
      //business logic
      basicEM.Update(entity)
      if(//condition) {
          throw New RollBackException("//message")
      }
      //business logic
    }
}

And here is my BasicEM class

@Component
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public class BasicEM {
    @PersistenceContext(unitName = "db1")
    private EntityManager em;

    public void update(Object target) {
        em.merge(target);
    }
}

So what i want is to call that update method, then if the condition is true undo the update. My intention is that when i throw the exception, the transaction ends and does not commit the update. But i am wrong and the update is already done. Please help me to achieve my goal.

CodePudding user response:

In order to achieve what you want you will need to have a transaction already in the Service method. The default propagation type for @Transactional(value = "transactionManager", rollbackFor = Exception.class) is Propagation.REQUIRED which means that if your Service is already included in a transaction, the basicEM.Update(entity) will also be included in such transaction.

@Service
public class UserManager implements IUserManager {

    private final IBasicEM basicEM;

    public ApplicantInfoManager(IBasicEM basicEM) {
        this.basicEM = basicEM;
    }

    @Override
    @Transactional(value = "transactionManager", 
       propagation = Propagation.REQUIRES_NEW, rollbackFor = RollBackException.class)
    public boolean purgeUser(Long id) throws Exception {
      //business logic
      basicEM.Update(entity)
      if(//condition) {
          throw New RollBackException("//message")
      }
      //business logic
    }
}

If RollBackException is a RuntimeException you don't need to explicitly configure that the transaction should rollback when it is thrown. If it is not, then you need to configure it as follows: @Transactional(value = "transactionManager", propagation = Propagation.REQUIRES_NEW, rollbackFor = RollBackException.class).

  • Related