交易了Jms组件,交易了骆驼路线

时间:2020-02-16 11:01:42

标签: apache-camel spring-transactions spring-camel

浏览《骆驼在行动》一书后,我遇到了以下疑问。

我有2条路线以下

A。
from("file:/home/src") //(A.1) .transacted("required") //(A.2) .bean("dbReader", "readFromDB()") //(A.3) only read from DB .bean("dbReader", "readFromDB()") //(A.4) only read from DB .to("jms:queue:DEST_QUEUE") //(A.5)

问题:
A.a.真的需要(A.2)交易吗?

A.b。如果对#a的回答为是,那么“必需”策略的关联事务管理器应该是什么?应该是JmsTransactionManager还是JpaTransactionManager?

A.c。因为DEST_QUEUE在生产者端,所以是否需要处理(A.5)中的JMS组件?

B。 from("jms:queue:SRC_QUEUE") //(B.1) transactional jms endpoint .transacted("required") //(B.2) .bean("someBean", "someMethod()") //(B.3) simple arithmetic computation .to("jms1:queue:DEST_QUEUE") //(B.4)

SRC_QUEUE和DEST_QUEUE是不同jms代理的队列

问题:

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

B.b。由于DEST_QUEUE在生产者端,因此(B.4)中的JMS组件是否需要交易?

2 个答案:

答案 0 :(得分:0)

谈论骆驼交易处理的很好的问题。

一般性说明:谈论骆驼交易时,它意味着使用从具有交易能力的系统(例如数据库或JMS代理)中进行交易。路线中的transacted语句必须紧跟from 语句,因为它始终与消耗量相关

A.a。真的需要(A.2)交易吗?

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

A.b。如果对#a的回答为是,则...?

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

A.c。因为DEST_QUEUE在生产者端,所以是否需要处理(A.5)中的JMS组件?

不确定,但我不这么认为。生产者尝试将消息传递给代理。 交易用于启用回滚,但是如果代理未收到数据,回滚会做什么?

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

这取决于,因为SRC和DEST属于不同的经纪人

  • 如果您希望经纪人之间进行端到端交易,则需要使用XA交易管理器,然后必须将路由标记为transacted
  • 如果您同意消费者交易,则可以configure the JMS component for it,并省略Spring Tx管理器和Camel transacted语句。

要澄清最后一点:如果您通过本地经纪人交易进行消费,骆驼直到成功处理路由后才会提交消息。因此,如果发生任何错误,将发生回滚并重新发送该消息。

在大多数情况下,这是完全可以的,但是,两个不同的代理仍然可能发生的事情是,路由已成功处理,邮件已传递到DEST代理,但Camel无法再对SRC代理进行提交。然后发生重新交付,再次处理该路由,并且消息多次发送到DEST代理

在我看来,XA交易的复杂性比本地经纪人交易的罕见情况要难得多。但这是一个非常主观的观点,也许还取决于您正在使用的上下文或数据。

需要注意的是:如果SRC和DEST经纪人相同,则本地经纪人交易就100%足够!绝对不需要Spring Tx管理器和Camel transacted

B.b。由于DEST_QUEUE在生产者端,因此(B.4)中的JMS组件是否需要交易?

与B.a.的答案相同

答案 1 :(得分:0)

下午好,

我想花点时间回答您的问题。我将解决“ B”类问题。

WRT:

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

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

将路由标记为“已处理”将启动JTA事务上下文。请注意,PlatformTransactionManager必须是JtaTransactionManager。当调用“ to”组件时,用于消息发送的本地JMS事务将与用于消息get的本地事务同步。 (JTA同步事务)。这意味着当远程代理确认发送的提交时,发送将获得回调。届时,将接收消息。这是“ 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>

为org.springframework.jms.connection.JmsTransactionManager启用DEBUG日志记录,为您使用的JTA事务管理器启用DEBUG / TRACE级别日志记录。