我有一个持久的事务性队列,包含我需要通过异步协议发送的消息。每条消息都需要在自己的事务中发送,但是在给定时间在线的消息数量排除了使用每个消息的消息,而吞吐量要求排除了持续存在的中间消息的状态。
查看JmsTransactionManager
的代码,我看到它正在使用TransactionSynchronizationManager
,它将交易资源存储在ThreadLocal
中。因此,似乎我需要实现一个PlatformTransactionManager
来以某种方式在单个线程中管理多个事务。这个似乎有点极端......
是否有一些Spring Integration单元可以避免这种复杂性? 我应该更喜欢看JTA / XA吗?
答案 0 :(得分:1)
Spring Integration中所有这些基于队列的通道都只在默认情况下将消息存储在内存中。当需要持久性时,您可以在“message-store
”元素中提供“queue
”属性以引用持久性MessageStore实现,也可以将本地通道替换为持久性支持的属性。代理,例如JMS支持的通道或通道适配器。后一个选项允许您利用任何JMS提供程序的实现来实现消息持久性。
您可以通过添加message-store属性为任何QueueChannel
配置邮件存储,如下所示。
Spring Integration通过以下方式提供对消息存储模式的支持:a)定义org.springframework.integration.store.MessageStore
策略接口,b)提供此接口的多个实现,以及c)在具有该功能的所有组件上公开消息存储属性缓冲消息,以便您可以注入任何实现MessageStore接口的实例。
我的示例使用了JDBC Message Store,但也有其他一些选项可供使用。
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${my.jdbc.driver}"/>
<property name="url" value="${my.jdbc.url}"/>
<property name="username" value="${my.jdbc.username}"/>
<property name="password" value="${my.jdbc.password}"/>
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<property name="connectionProperties" value="SetBigStringTryClob=true;"/>
</bean>
<!-- The poller is needed by any of the QueueChannels -->
<integration:poller id="myPoller" fixed-rate="5000" default="true"/>
<!-- The MessageStore is needed to persist messages used by any of the QueueChannels -->
<int-jdbc:message-store id="myMessageStore" data-source="myDataSource" table-prefix="MY_INT_"/>
<!-- Main entry point into the process -->
<integration:gateway id="myGateway"
service-interface="com.mycompany.myproject.integration.gateways.myGateway"
default-request-channel="myGatewayChannel"
/>
<!-- Map the initial input channel to the first step, MyFirstService -->
<integration:channel id="myGatewayChannel">
<integration:queue capacity="1000"/>
<integration:queue message-store="myMessageStore" capacity="1000"/>
</integration:channel>
<!-- Step 1: My First Service -->
<integration:service-activator
id="myFirstServiceActivator"
input-channel="myGatewayChannel"
output-channel="myNextChannel"
ref="myFirstService"
method="process"/>
<!-- LONG running process. Setup asynchronous queue channel. -->
<integration:channel id="myNextChannel">
<integration:queue capacity="1000"/>
<integration:queue message-store="myMessageStore" capacity="1000"/>
</integration:channel>