[
https://issues.apache.org/jira/browse/CAMEL-10902?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15887598#comment-15887598
]
Claus Ibsen commented on CAMEL-10902:
-------------------------------------
This is by design to rollback on all exceptions.
> 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
> 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)