Apache camel 已处理Jms组件和驼峰路由

Apache camel 已处理Jms组件和驼峰路由,apache-camel,spring-transactions,spring-camel,Apache Camel,Spring Transactions,Spring Camel,翻阅《骆驼在行动》一书后,我遇到了以下疑问 我有以下两条路线 A. from(“文件:/home/src”)/(A.1) .已交易(“必需”)/(A.2) .bean(“dbReader”、“readFromDB()”/(A.3)仅从数据库读取 .bean(“dbReader”、“readFromDB()”/(A.4)仅从DB读取 .to(“jms:queue:DEST_queue”)//(A.5) 问题: 在(A.2)中交易的A.A.在这里真的需要吗 A.b.如果A的答案是肯定的,那么“必需”

翻阅《骆驼在行动》一书后,我遇到了以下疑问

我有以下两条路线

A.
from(“文件:/home/src”)/(A.1)
.已交易(“必需”)/(A.2)
.bean(“dbReader”、“readFromDB()”/(A.3)仅从数据库读取
.bean(“dbReader”、“readFromDB()”/(A.4)仅从DB读取
.to(“jms:queue:DEST_queue”)//(A.5)

问题:
在(A.2)中交易的A.A.在这里真的需要吗

A.b.如果A的答案是肯定的,那么“必需”策略的关联交易经理应该是什么?应该是jmtransactionmanager还是JpaTransactionManager

由于DEST_队列位于生产者端,所以(A.5)中的JMS组件是否需要进行事务处理

B。
from(“jms:queue:SRC_queue”)/(B.1)事务性jms端点
.已交易(“必需”)/(B.2)
.bean(“someBean”、“someMethod()”/(B.3)简单算术计算
.to(“jms1:queue:DEST_queue”)/(B.4)

SRC_队列和DEST_队列是不同jms代理的队列

问题:

B.a.(B.1)中的JMS组件被标记为已事务处理,因此在这种情况下,路由是否需要按照(B.2)中所述进行事务处理

B.B.由于DEST_队列位于生产者端,所以(B.4)中的JMS组件是否需要进行事务处理


非常好的问题来谈论骆驼交易处理

一般备注:当谈到Camel事务时,它意味着使用从支持事务的系统(如数据库或JMS代理)处理的事务。路线中的
交易的
语句必须立即跟随
from
语句,因为它总是与消费相关

在(A.2)中交易的A.A.在这里真的需要吗

不,不是。由于文件系统不支持事务处理,因此它在这方面没有任何帮助

A.b.如果A的答案是肯定的,那么

没有“文件系统事务管理器”

由于DEST_队列位于生产者端,所以(A.5)中的JMS组件是否需要进行事务处理

不确定,但我不这么认为。生产者试图将消息移交给代理事务用于启用回滚,但如果代理未收到数据,回滚可以做什么

B.a.(B.1)中的JMS组件被标记为已事务处理,因此在这种情况下,路由是否需要按照(B.2)中所述进行事务处理

这取决于,因为SRC和DEST在不同的代理上

  • 如果希望在代理之间进行端到端交易,则需要使用XA事务管理器,然后必须将路由标记为
    已交易
  • 如果您同意消费者事务处理,则可以删除Spring Tx manager和Camel
    Transact
    语句
为了澄清最后一点:如果您使用本地代理事务,在成功处理路由之前,Camel不会提交消息。因此,如果发生任何错误,将发生回滚,并重新传递消息

在大多数情况下,这是完全正常的,但是,在两个不同的代理中仍然可能发生的情况是,路由被成功处理,消息被传递到DEST broker,但是Camel不再能够针对SRC broker进行提交。然后发生重新交付,路由再处理一次,消息多次传递到DEST broker

在我看来,XA事务的复杂性比本地代理事务的非常罕见的边缘情况更难处理。但这是一个非常主观的观点,可能还取决于您使用的上下文或数据

重要的是要注意:如果SRC和DEST broker是相同的,那么本地的broker交易就100%足够了绝对不需要Spring Tx manager和Camel
事务处理

B.B.由于DEST_队列位于生产者端,所以(B.4)中的JMS组件是否需要进行事务处理

与B.a.的答案相同。

下午好

我想花一分钟时间回答你的问题。我将回答“B”边的问题

警告:

B.a.(B.1)中的JMS组件被标记为已事务处理,因此在这种情况下,路由是否需要按照(B.2)中所述进行事务处理

对。源组件和目标组件都需要标记为已事务处理。将组件标记为已事务将在源和目标会话上启动本地JMS事务。请注意,这是两个单独的本地JMS事务,由两个单独的JMStransActionManager管理

将路由标记为“已处理”将启动JTA事务上下文。请注意,PlatformTransactionManager必须是JtaTransactionManager。调用“to”组件时,用于消息发送的本地JMS事务将与用于消息获取的本地事务同步。(JTA同步事务)。这意味着当远程代理确认发送的提交时,发送将得到回调。此时,将提交消息receive。这是“dups OK”事务行为(不是XA)。您有一个窗口,其中消息已发送,但接收尚未确认

实际上,要让它工作起来是很棘手的。以下是一个示例:

<!-- ******************** Camel route definition ********************* -->
<camelContext allowUseOriginalMessage="false"
    id="camelContext-Bridge-Local" streamCache="true" trace="true" xmlns="http://camel.apache.org/schema/blueprint">
    <route id="amq-to-amq">
        <from id="from" uri="amqLoc:queue:IN"/>
        <transacted id="trans"/>
        <to id="to" uri="amqRem:queue:OUT"/>
    </route>
</camelContext>
<!-- ********************* Local AMQ configuration ************************** -->
<bean class="org.apache.activemq.camel.component.ActiveMQComponent" id="amqLoc">
    <property name="configuration">
        <bean class="org.apache.camel.component.jms.JmsConfiguration">
            <property name="connectionFactory" ref="AmqCFLocalPool"/>
            <property name="receiveTimeout" value="100000"/>
            <property name="maxConcurrentConsumers" value="3"/>
            <property name="cacheLevelName" value="CACHE_NONE"/>
            <property name="transacted" value="true"/>
        </bean>
    </property>
</bean>
<bean class="org.apache.activemq.jms.pool.PooledConnectionFactory" id="AmqCFLocalPool">
    <property name="maxConnections" value="1"/>
    <property name="idleTimeout" value="0"/>
    <property name="connectionFactory" ref="AmqCFLocal"/>
</bean>
<bean class="org.apache.activemq.ActiveMQConnectionFactory" id="AmqCFLocal">
    <property name="brokerURL" value="tcp://10.0.0.170:61616?jms.prefetchPolicy.all=0"/>
    <property name="userName" value="admin"/>
    <property name="password" value="admin"/>
</bean>
<!-- ********************* Remote AMQ configuration ************************** -->
<bean class="org.apache.activemq.camel.component.ActiveMQComponent" id="amqRem">
    <property name="configuration">
        <bean class="org.apache.camel.component.jms.JmsConfiguration">
            <property name="connectionFactory" ref="AmqCFRemotePool"/>
            <property name="transacted" value="true"/>
        </bean>
    </property>
</bean>
<bean class="org.apache.activemq.jms.pool.PooledConnectionFactory"
    destroy-method="stop" id="AmqCFRemotePool" init-method="start">
    <property name="maxConnections" value="1"/>
    <property name="idleTimeout" value="0"/>
    <property name="connectionFactory" ref="AmqCFRemote"/>
</bean>
<bean class="org.apache.activemq.ActiveMQConnectionFactory" id="AmqCFRemote">
    <property name="brokerURL" value="tcp://10.0.0.171:61616"/>
    <property name="userName" value="admin"/>
    <property name="password" value="admin"/>
</bean>