0

@Transactional isn't rolling back the transaction when I'm throwing the exception in a catch block.

@Transactional(rollbackFor = MyException.class)
public void testTransactional2() throws Exception {
    try {
        dao1.save(entity1);
        dao2.save(entity2);
        arrayList.get(999999); // intentionally cause an exception
    } catch (IndexOutOfBoundsException e) {
        throw new MyException(ErrorCode.UNABLE_TO_INSERT, e);
    }
}

dao1.save() and dao2.save() are both annotated with @Transactional themselves.

When I check the database, I see both the entities are persisted.

mohitmayank
  • 631
  • 2
  • 7
  • 20
  • 1
    Where is the method called from? See: https://stackoverflow.com/questions/3423972/spring-transaction-method-call-by-the-method-within-the-same-class-does-not-wo – Alan Hay Jan 15 '19 at 11:55
  • 1
    How are you calling this method and which database are you using. – M. Deinum Jan 15 '19 at 12:00
  • This method is called from another method in the same class which is NOT annotated as Transactional. The parent method is called from a controller. The thrown exception is caught there but I have tested it without catching as well - same result. – mohitmayank Jan 15 '19 at 12:17
  • The link I have posted above is relevant then. I think in this case you actually have 2 separate transactions executed - those defined at the DAO level - as the transaction defined at the service layer has no effect. – Alan Hay Jan 15 '19 at 12:19
  • 1
    If you are calling it from the same class the `@Transactional` is useless. You have 2 transactions for both save methods. Calling proxied methods on the same class won't work as they don't pass though the proxy. – M. Deinum Jan 15 '19 at 12:24
  • By default, Spring @Transactional uses Propagation.REQUIRED. So shouldn't the transactions in the two DAOs use the existing transaction? – mohitmayank Jan 16 '19 at 05:04
  • As is clearly explained above your `@Transactional` in question has zero effect. I am not sure how his could be made any clearer. – Alan Hay Jan 16 '19 at 10:47
  • I got that (calling a `@Transactional` method from another method within the same class renders the annotation useless). I was trying to understand why this is the case. Thanks for your explanation. :) – mohitmayank Jan 17 '19 at 05:39

1 Answers1

-1

Note : @Transactional is setup to rollback, by default, only when an unchecked exception is thrown.

Along with this remove your throws clause , instead throws MyException.

  • I am throwing `MyException` from the catch block and `@Transactional` is set to `rollbackFor=MyException.class`. So there's not problem with that. – mohitmayank Jan 16 '19 at 06:14