此内容没有您所选择的语言版本。

5.2. Demarcation by Transactional Endpoints


Overview

If a consumer endpoint at the start of a route accesses a resource, the transacted() command is of no use, because it initiates the transaction after an exchange is polled. In other words, the transaction starts too late to include the consumer endpoint within the transaction scope. The correct approach in this case is to make the endpoint itself responsible for initiating the transaction. An endpoint that is capable of managing transactions is known as a transactional endpoint.

Sample route with JMS endpoint

Figure 5.2, “Demarcation by Transactional Endpoints” shows an example of a route that is made transactional by the presence of a transactional endpoint at the start of the route (in the from() command). All of the route nodes are included in the transaction scope. In this example, all of the endpoints in the route access a JMS resource.

Figure 5.2. Demarcation by Transactional Endpoints

Demarcation by Transactional Endpoints
There are two different models of demarcation by transactional endpoint, as follows:
  • General case—normally, a transactional endpoint demarcates transactions as follows: when an exchange arrives at the endpoint (or when the endpoint successfully polls for an exchange), the endpoint invokes its associated transaction manager to begin a transaction (attaching it to the current thread); and when the exchange reaches the end of the route, the transactional endpoint invokes the transaction manager to commit the current transaction.
  • JMS endpoint with InOut exchange—when a JMS consumer endpoint receives an InOut exchange and this exchange is routed to another JMS endpoint, this must be treated as a special case. The problem is that the route can deadlock, if you try to enclose the entire request/reply exchange in a single transaction. For details of how to resolve this problem, see Section 3.3, “InOut Message Exchange Pattern”.

Route definition in Java DSL

The following Java DSL example shows how to define a transactional route by starting the route with a transactional endpoint:
from("jmstx:queue:giro")
    .to("jmstx:queue:credits")
    .to("jmstx:queue:debits");
Where the transaction scope encompasses the endpoints, jmstx:queue:giro, jmstx:queue:credits, and jmstx:queue:debits. If the transaction succeeds, the exchange is permanently removed from the giro queue and pushed on to the credits queue and the debits queue; if the transaction fails, the exchange does not get put on to the credits and debits queues and the exchange is pushed back on to the giro queue (by default, JMS will automatically attempt to redeliver the message).
The JMS component bean, jmstx, must be explicitly configured to use transactions, as follows:
<beans ...>
  <bean id="jmstx" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="configuration" ref="jmsConfig" /> 
  </bean> 

  <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> 
      <property name="connectionFactory" ref="jmsConnectionFactory"/> 
      <property name="transactionManager" ref="jmsTransactionManager"/> 
      <property name="transacted" value="true"/> 
  </bean>
  ...
</beans>
Where the transaction manager instance, jmsTransactionManager, is associated with the JMS component and the transacted property is set to true to enable transaction demarcation for InOnly exchanges. For the complete Spring XML configuration of this component, see Example 3.1, “JMS Transaction Manager Configuration”.

Route definition in Spring XML

The preceding route can equivalently be expressed in Spring XML, as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ... >

  <camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
      <from uri="jmstx:queue:giro"/>
      <to uri="jmstx:queue:credits"/>
      <to uri="jmstx:queue:debits"/>
    </route>
  </camelContext>

</beans>

transacted() not required

The transacted() DSL command is not required in a route that starts with a transactional endpoint. Nevertheless, assuming that the default transaction policy is PROPAGATION_REQUIRED (see Section 5.3, “Propagation Policies”), it is usually harmless to include the transacted() command, as in this example:
from("jmstx:queue:giro")
    .transacted()
    .to("jmstx:queue:credits")
    .to("jmstx:queue:debits");
However, it is possible for this route to behave in unexpected ways—for example, if a single TransactedPolicy bean having a non-default propagation policy is created in Spring XML (see the section called “Default transaction manager and transacted policy”)—so it is generally better not to include the transacted() DSL command in routes that start with a transactional endpoint.

Transactional endpoints

The following Apache Camel components act as transactional endpoints when they appear at the start of a route (for example, if they appear in the from() DSL command). That is, these endpoints can be configured to behave as a transactional client and they can also access a transactional resource.
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.