Frank
Frank

Reputation: 21

Java EJB ApplicationException: Is there a way to have a differentiated rollback behavior for caught and uncaught Exceptions?

I have a problem with a caught RuntimeException marked as @ApplicationException(rollback=true) rolling back my database transaction and killing the transaction for the following actions.

@ApplicationException(rollback = true)
public class XyzValidationException extends RuntimeException {
   ...
}

The process is a batch import process, which is importing mass data in chunks. When the transction is rolled back, the whole chunk is rolled back and after that selected for import again, so the whole thing repeats in an endless loop.

The applicationserver is a JBoss 7.1 and the database is an Oracle 11.2.

I want to catch the exception, mark the import source entity as faulty, log something, and carry on with the rest of the data.

But catching the exception doesn't prevent the transaction from being rolled back. I have read about it now and understood this behavior is normal. But the thing is, how do you do it then? How do you configure the exception to not roll back when it's caught, and to still do a rollback, when it's uncaught? I could set the exceptions' annotation to @ApplicationException(rollback=false), but then i would prevent a rollback in a situation, where the exception is thrown an not caught, right? In other processes, a Rollback could be sensible, when this exception is thrown. There, I would just not want to catch ist. Does anyone have an idea, how I could achieve this?

I have tried already to change the exception to a checked exception (... extends Exception) and left the annotation with rollback=true. It didnt change the behavior (I was thinkig/hoping that the rollback=true would maybe just take effect on an uncaught exception, and do the trick in my case... but no) Then I tried the checked exception with rollback=false, and as expected, it did the trick. But as described already, I don't want to deactivate the rollback completely... only when the exception is caught. And, if possible, I'd like to stick to the RuntimeException, as we have this 'Policy' to use RuntimeExceptions wherever possible, and the necessary throws-declarations would spread across the application...

Thanks in advance...

Frank

Upvotes: 2

Views: 1578

Answers (1)

xxxception
xxxception

Reputation: 955

You have different ways how to manage this problem.

  1. Use application exceptions. By default, all checked exceptions are application exception (except the RemoteException). In the CMT model, such kinds of exceptions don't cause an automatic rollback. Thus, you can handle occurred exception during processing a chunk and do something staff like log smth without rollback. For rest cases, should use unchecked exceptions which cause an automatic rollback.
  2. If you have some "policy" sticking to unchecked exceptions in your code. You can declare runtime exception like XyzValidationException and annotate it with @ApplicationException(rollback = true), so in the case where it is thrown the transaction won't be rollbacked. For all other code, where there is necessary to make rollback you can use RuntimeException (which has rollback = false by default).
  3. Have a look at CDI if it's possible in your project. It provides @Transactional which includes such properties as rollbackOn and dontRollbackOn.

Upvotes: 1

Related Questions