浏览《骆驼在行动》一书后,我遇到了以下疑问。
我有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组件是否需要交易?
答案 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属于不同的经纪人。
transacted
。 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级别日志记录。