[ 
https://issues.apache.org/jira/browse/CAMEL-10902?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-10902.
---------------------------------
    Resolution: Won't Fix
      Assignee: Claus Ibsen

> TransactionErrorHandler treats all exceptions as a rollback (different to 
> Spring)
> ---------------------------------------------------------------------------------
>
>                 Key: CAMEL-10902
>                 URL: https://issues.apache.org/jira/browse/CAMEL-10902
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-spring
>    Affects Versions: 2.18.2
>            Reporter: Nick Houghton
>            Assignee: Claus Ibsen
>            Priority: Minor
>
> It appears while debugging a JDBC transaction commit issue that the behaviour 
> of TransactionErrorHandler is different to the expected behaviour of the 
> underlying Spring TransactionTemplate classes. I'm not sure this is by design 
> or not?
> The standard @Transactional annotation people are used to will only rollback 
> a transaction when a RuntimeException is caught, in all other cases it will 
> commit, this appears to be different to camels abstraction which will 
> rollback if there is any exchange.getException() || exchange.isRollback() 
> set. Should this be more consistent with the underlying Spring impl and be an 
> instanceof RuntimeException instead?
> Currently:
> {code}
> transactionTemplate.execute(new TransactionCallbackWithoutResult() {
>             protected void doInTransactionWithoutResult(TransactionStatus 
> status) {
>                 // wrapper exception to throw if the exchange failed
>                 // IMPORTANT: Must be a runtime exception to let Spring 
> regard it as to do "rollback"
>                 RuntimeException rce;
>                 // and now let process the exchange by the error handler
>                 processByErrorHandler(exchange);
>                 // after handling and still an exception or marked as 
> rollback only then rollback
>                 if (exchange.getException() != null || 
> exchange.isRollbackOnly()) {
>                     // wrap exception in transacted exception
>                     if (exchange.getException() != null) {
>                         rce = 
> ObjectHelper.wrapRuntimeCamelException(exchange.getException());
>                     } else {
>                         // create dummy exception to force spring transaction 
> manager to rollback
>                         rce = new TransactionRollbackException();
>                     }
>                     if (!status.isRollbackOnly()) {
>                         status.setRollbackOnly();
>                     }
>                     // throw runtime exception to force rollback (which works 
> best to rollback with Spring transaction manager)
>                     if (log.isTraceEnabled()) {
>                         log.trace("Throwing runtime exception to force 
> transaction to rollback on {}", transactionTemplate.getName());
>                     }
>                     throw rce;
>                 }
>             }
>         });
> {code}
> Could be:
> {code}
> transactionTemplate.execute(new TransactionCallbackWithoutResult() {
>             protected void doInTransactionWithoutResult(TransactionStatus 
> status) {
>                 // wrapper exception to throw if the exchange failed
>                 // IMPORTANT: Must be a runtime exception to let Spring 
> regard it as to do "rollback"
>                 RuntimeException rce;
>                 // and now let process the exchange by the error handler
>                 processByErrorHandler(exchange);
>                 // after handling and still an exception or marked as 
> rollback only then rollback
>                 if (exchange.getException() instanceof RuntimeException || 
> exchange.isRollbackOnly()) {
>                     // wrap exception in transacted exception
>                     if (exchange.getException() != null) {
>                         rce = 
> ObjectHelper.wrapRuntimeCamelException(exchange.getException());
>                     } else {
>                         // create dummy exception to force spring transaction 
> manager to rollback
>                         rce = new TransactionRollbackException();
>                     }
>                     if (!status.isRollbackOnly()) {
>                         status.setRollbackOnly();
>                     }
>                     // throw runtime exception to force rollback (which works 
> best to rollback with Spring transaction manager)
>                     if (log.isTraceEnabled()) {
>                         log.trace("Throwing runtime exception to force 
> transaction to rollback on {}", transactionTemplate.getName());
>                     }
>                     throw rce;
>                 }
>             }
>         });
> {code}
> This enable my desired behaviour where a subroute can throw an exception to 
> present an error to the user, but still have work committed if desired.
> At the moment it seems like the only option for not rolling back a 
> transaction is to process the exception in the subroute itself, which is not 
> what I want to do rather than letting it bubble up to the calling route.
> If not the given change, would it be possible to allow what drives a rollback 
> to be configurable? much like Spring 'rollbackFor' parameter.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to