28
@Transactional(rollbackFor = MyCheckedException.class)
public void foo() {
    throw new RuntimeException();    
}

Will this transaction get rolled back, or do I need to include RuntimeException.class in the annotation as well?

Alex Beardsley
  • 20,988
  • 15
  • 52
  • 67

3 Answers3

26

No need to include RuntimeException in rollbackFor list. It will handle that even if you do not mention it.

I've tried it out for jdbcTemplate:-

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = MyException.class)
public void updateSalary(final int increment){
    jdbcTemplate.update("update EMPLOYEE set emp_salary = emp_salary + ?", increment);
    throw new RuntimeException("update exception");
}
Output:
After Insertion:
1 Deepak 35000
2 Yogesh 35000
3 Aditya 35000

update exception
After Update
1 Deepak 35000
2 Yogesh 35000
3 Aditya 35000
Gray
  • 115,027
  • 24
  • 293
  • 354
deepakraut
  • 893
  • 1
  • 10
  • 17
  • @AlexBeardsley thnx for pointing out the mistake... i modified the answer.. I re-ran the code.. and yes, you need not include runtime exception in rollbackFor list. – deepakraut Oct 12 '12 at 09:34
9

However, please note that the Spring Framework's transaction infrastructure code will, by default, only mark a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. (Errors will also - by default - result in a rollback.) Checked exceptions that are thrown from a transactional method will not result in the transaction being rolled back.

Source

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
  • 9
    This still does not explain whether rollbackFor is additive or replacing the default behaviour on RuntimeException/Error. – Mauro Molinari Nov 02 '18 at 10:15
4

So it can roll back with CheckedException as well (RuntimeException by default), example:

@Transactional(rollbackFor = Exception.class)
public void save(Book book) throws Exception {
    bookRepository.save(book);
    System.out.println("Saved in transcation.");
    // No data is persisted
    if (true) {
        throw new Exception();
    }
}
Bằng Rikimaru
  • 1,512
  • 2
  • 24
  • 50
  • 1
    @AkshayKasar If I didn't try, I wouldn't have posted. – Bằng Rikimaru Apr 10 '18 at 11:32
  • 1
    From my experience, when you do this people start copying your code without understanding how it works, and then it becomes difficult to review their code as you don't know their real intentions regarding rollback/exception handling. So I prefer only to list checked exceptions in the `rollbackFor`. In most cases this will be the same as what is in your `throws` declaration, so it isn't very difficult to maintain. By the same token, I would avoid `throws Exception` in most cases, as it will be impossible to judge which checked exceptions are actually thrown. – rougou Mar 04 '19 at 02:00