camel-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Piotr Klimczak (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CAMEL-8424) Transaction being propagated ignoring REQUIRES_NEW when using direct component
Date Tue, 03 Mar 2015 10:19:04 GMT

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

Piotr Klimczak updated CAMEL-8424:
----------------------------------
    Description: 
I found that when we are using exactly same propagation policy bean in different routes used
together with "direct" component, then TransactionErrorHandler always propagates current transaction
even if our policy is "PROPAGATION_REQUIRES_NEW".

The failing code is:
{code}
    public TransactionErrorHandler(CamelContext camelContext, Processor output, CamelLogger
logger, 
            Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy
exceptionPolicyStrategy,
            TransactionTemplate transactionTemplate, Predicate retryWhile, ScheduledExecutorService
executorService,
            LoggingLevel rollbackLoggingLevel) {

        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null,
false, retryWhile, executorService);
        setExceptionPolicy(exceptionPolicyStrategy);
        this.transactionTemplate = transactionTemplate;
        this.rollbackLoggingLevel = rollbackLoggingLevel;
        this.transactionKey = ObjectHelper.getIdentityHashCode(transactionTemplate);
    }

    @Override
    public void process(Exchange exchange) throws Exception {
        // we have to run this synchronously as Spring Transaction does *not* support
        // using multiple threads to span a transaction
        if (exchange.getUnitOfWork().isTransactedBy(transactionKey)) {
            // already transacted by this transaction template
            // so lets just let the error handler process it
            processByErrorHandler(exchange);
        } else {
            // not yet wrapped in transaction so lets do that
            // and then have it invoke the error handler from within that transaction
            processInTransaction(exchange);
        }
    }
{code}
So then for each policy there is a hash code created, which then is used to verify whether
current route is already transacted by this transaction policy.
This makes "PROPAGATION_REQUIRES_NEW" ignored when used with "direct" component.

So for example:
{code}
                from("activemq:queue:start").routeId("route1")
                        .transacted("PROPAGATION_REQUIRES_NEW")
                        .setExchangePattern(ExchangePattern.InOnly)
                        .to("activemq:queue:result1")
                        .to("direct:route2")
                        .throwException(new RuntimeException("Expected!"));

                from("direct:route2").routeId("route2")
                        .transacted("PROPAGATION_REQUIRES_NEW")
                        .setExchangePattern(ExchangePattern.InOnly)
                        .to("activemq:queue:result2");
{code}

The above route suppose to work in 2 different transactions, as our propagation is REQUIRES_NEW
for both of them. But due to hash code verification and optimisation, route2 will participate
in same transaction as route1 instead of new.
This is rather buggy.

Will create pull request in minutes.

  was:
I found that when we are using exactly same propagation policy bean in different routes used
together with "direct" component, then TransactionErrorHandler always propagates current transaction
even if our policy is "PROPAGATION_REQUIRES_NEW".

The failing code is:
{code}
    public TransactionErrorHandler(CamelContext camelContext, Processor output, CamelLogger
logger, 
            Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy
exceptionPolicyStrategy,
            TransactionTemplate transactionTemplate, Predicate retryWhile, ScheduledExecutorService
executorService,
            LoggingLevel rollbackLoggingLevel) {

        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null,
false, retryWhile, executorService);
        setExceptionPolicy(exceptionPolicyStrategy);
        this.transactionTemplate = transactionTemplate;
        this.rollbackLoggingLevel = rollbackLoggingLevel;
        this.transactionKey = ObjectHelper.getIdentityHashCode(transactionTemplate);
    }

    @Override
    public void process(Exchange exchange) throws Exception {
        // we have to run this synchronously as Spring Transaction does *not* support
        // using multiple threads to span a transaction
        if (exchange.getUnitOfWork().isTransactedBy(transactionKey)) {
            // already transacted by this transaction template
            // so lets just let the error handler process it
            processByErrorHandler(exchange);
        } else {
            // not yet wrapped in transaction so lets do that
            // and then have it invoke the error handler from within that transaction
            processInTransaction(exchange);
        }
    }
{code}
So then for each policy there is a hash code created, which then is used to verify whether
current route is already transacted by this transaction policy.
This makes "PROPAGATION_REQUIRES_NEW" ignored when used with "direct" component.

So for example:
{code}
                from("activemq:queue:start").routeId("route1)
                        .transacted("PROPAGATION_REQUIRES_NEW")
                        .setExchangePattern(ExchangePattern.InOnly)
                        .to("activemq:queue:result1")
                        .to("direct:route2")
                        .throwException(new RuntimeException("Expected!"));

                from("direct:route2").routeId("route2)
                        .transacted("PROPAGATION_REQUIRES_NEW")
                        .setExchangePattern(ExchangePattern.InOnly)
                        .to("activemq:queue:result2");
{code}

The above route suppose to work in 2 different transactions, as our propagation is REQUIRES_NEW
for both of them. But due to hash code verification and optimisation, route2 will participate
in same transaction as route1 instead of new.
This is rather buggy.

Will create pull request in minutes.


> Transaction being propagated ignoring REQUIRES_NEW when using direct component
> ------------------------------------------------------------------------------
>
>                 Key: CAMEL-8424
>                 URL: https://issues.apache.org/jira/browse/CAMEL-8424
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-spring
>    Affects Versions: 2.10.7, 2.11.4, 2.13.3, 2.14.1, 2.15.0
>            Reporter: Piotr Klimczak
>            Assignee: Claus Ibsen
>            Priority: Minor
>             Fix For: 2.13.4, 2.14.3, 2.15.0
>
>
> I found that when we are using exactly same propagation policy bean in different routes
used together with "direct" component, then TransactionErrorHandler always propagates current
transaction even if our policy is "PROPAGATION_REQUIRES_NEW".
> The failing code is:
> {code}
>     public TransactionErrorHandler(CamelContext camelContext, Processor output, CamelLogger
logger, 
>             Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy
exceptionPolicyStrategy,
>             TransactionTemplate transactionTemplate, Predicate retryWhile, ScheduledExecutorService
executorService,
>             LoggingLevel rollbackLoggingLevel) {
>         super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null,
null, false, retryWhile, executorService);
>         setExceptionPolicy(exceptionPolicyStrategy);
>         this.transactionTemplate = transactionTemplate;
>         this.rollbackLoggingLevel = rollbackLoggingLevel;
>         this.transactionKey = ObjectHelper.getIdentityHashCode(transactionTemplate);
>     }
>     @Override
>     public void process(Exchange exchange) throws Exception {
>         // we have to run this synchronously as Spring Transaction does *not* support
>         // using multiple threads to span a transaction
>         if (exchange.getUnitOfWork().isTransactedBy(transactionKey)) {
>             // already transacted by this transaction template
>             // so lets just let the error handler process it
>             processByErrorHandler(exchange);
>         } else {
>             // not yet wrapped in transaction so lets do that
>             // and then have it invoke the error handler from within that transaction
>             processInTransaction(exchange);
>         }
>     }
> {code}
> So then for each policy there is a hash code created, which then is used to verify whether
current route is already transacted by this transaction policy.
> This makes "PROPAGATION_REQUIRES_NEW" ignored when used with "direct" component.
> So for example:
> {code}
>                 from("activemq:queue:start").routeId("route1")
>                         .transacted("PROPAGATION_REQUIRES_NEW")
>                         .setExchangePattern(ExchangePattern.InOnly)
>                         .to("activemq:queue:result1")
>                         .to("direct:route2")
>                         .throwException(new RuntimeException("Expected!"));
>                 from("direct:route2").routeId("route2")
>                         .transacted("PROPAGATION_REQUIRES_NEW")
>                         .setExchangePattern(ExchangePattern.InOnly)
>                         .to("activemq:queue:result2");
> {code}
> The above route suppose to work in 2 different transactions, as our propagation is REQUIRES_NEW
for both of them. But due to hash code verification and optimisation, route2 will participate
in same transaction as route1 instead of new.
> This is rather buggy.
> Will create pull request in minutes.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message