0

I have a transactional method and I'd like to call an other method which may throw a RuntimeException.

The problem is that the transaction gets marked as rollbackOnly when the exception is thrown.

The other method call itself is in a try-catch block, but I think the transaction gets marked when the other method returns by throwing an exception.

Example:

MyService.java

@Service
public class MyService {

    @Autowired
    private MyUtils utils;

    @Autowired
    private MyCrudRepository repository;

    @Transactional
    public void publicMethod() {
       try {
           utils.otherPublicMethod();
       } catch (Exception ex) {
           ex.printStackTrace();
       }

       // RollbackException: Transaction marked as rollbackOnly
       // Even though I caught the exception from the method call itself
       repository.save(new MyEntity());
    }
}

MyUtils.java

@Component
public class MyUtils {

    // Does not use transactions, repositories
    // But I think it inherits the transaction and marks it as rollbackOnly
    public void otherPublicMethod() {

        // Maybe this is seen as an uncaught exception
        throw new RuntimeException();
    }
}

Edit:

I don't think this is a duplicate of Does Specifying @Transactional rollbackFor Also Include RuntimeException, because the exception is eventually caught.
The problem may be similar, as it also involves transactions and rollbacks.

1 Answers1

0

Annotation @Transactional has parameters such as rollbackFor and no-rollback-for with which you can say which exceptions will cause or will not cause rollback. For instance you can write:

@Transactional(rollbackFor = {RuntimeException.class})

Which will cause rollback upon RuntimeException. However, I believe that RuntimeException causes rollback by default. So you probably have to specify this exception in no-rollback-for clause. For details see Transaction Management and look for "16.5.5 settings" paragraph

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • Setting a `noRollBackFor` value for the `@Transactional` annotation on the method would mean it never rolls back on a `RuntimeException`. What I would like to do is to roll back only on a _really_ uncaught `RuntimeException`. – w9n7cxx5fM8 Jul 25 '18 at 15:08
  • If you catch your exception within method marked @Transactional then that exception should not influence your transactional behavior. there must be other exception somewhere in your method that you didn't catch – Michael Gantman Jul 25 '18 at 15:18