线程轮询jdbc:inbound-channel-adapter回滚事务,但发送了MQ消息

时间:2019-11-10 04:29:04

标签: spring-integration

我正在使用 jdbc:inbound-channel-adapter 作为 transactional 来轮询 50个数据库记录。这意味着所有 50条记录将在一次(相同)交易中处理。我希望它们可以在同一笔交易中处理。

在示例代码中, ProcessIndividualRecord :: updateDB()更新数据库中的状态,然后 notificationJMSChannel 将消息发送到MQ。

如果在处理第50条记录 updateDB方法中发生异常,则框架回滚所有先前更新的 49条记录,并且控制权转到 ProcessorExceptionHandler 第50条记录

我的挑战是“ notificationJMSChannel ”已经发送了先前的 49条记录给MQ。

我该如何回退那些?

<int-jdbc:inbound-channel-adapter
    id="initial.poller"
    query="${poller.get}"
    update="${poller.update}"
    max-rows="${poller.maxRow:50}"
    row-mapper="pollerRowMapper"
    data-source="dataSource" channel="deliveryContactTypeChannel">
        <int:transactional/>
</int-jdbc:inbound-channel-adapter>

<int:channel id="deliveryContactTypeChannel" />

<int:splitter id="splitDeliveryContactType"
    ref="deliveryContactTypeMessageProcessor" method="handleJdbcMessage"
    input-channel="deliveryContactTypeChannel"
    output-channel="processIndividualRecordChannel" />

<int:service-activator id="statusUpdate"
    input-channel="processIndividualRecordChannel"
    output-channel="notificationJMSChannel"
    ref="processIndividualRecord" method="updateDB" />

<!-- send MQ message -->
<int:channel id="notificationJMSChannel"></int:channel>

<int-jms:outbound-channel-adapter
    id="jmsOut" channel="notificationJMSChannel" 
    destination="senderTopic" jms-template="jmsQueueTemplate">
</int-jms:outbound-channel-adapter>

<!-- Error handling -->
<int:channel id="jmsErrorChannel" />

<int:header-enricher id="errorMsg.HeaderEnricher"
    input-channel="errorChannel"
    output-channel="jmsErrorChannel">
    <int:header name="failpayload" expression="payload.failedMessage" />
</int:header-enricher>

<int:service-activator
    input-channel="jmsErrorChannel" method="handleException">
    <bean class="com.digital.alerts.integration.ProcessorExceptionHandler" />
</int:service-activator>

1 个答案:

答案 0 :(得分:1)

如果您处理JEE容器或 chain DataSource和JMS事务管理器,则需要考虑使用JtaTransactionManager。{p}

在Spring Data中参见ChainedTransactionManager实施:

/**
 * {@link PlatformTransactionManager} implementation that orchestrates transaction creation, commits and rollbacks to a
 * list of delegates. Using this implementation assumes that errors causing a transaction rollback will usually happen
 * before the transaction completion or during the commit of the most inner {@link PlatformTransactionManager}.
 * <p />
 * The configured instances will start transactions in the order given and commit/rollback in <em>reverse</em> order,
 * which means the {@link PlatformTransactionManager} most likely to break the transaction should be the <em>last</em>
 * in the list configured. A {@link PlatformTransactionManager} throwing an exception during commit will automatically
 * cause the remaining transaction managers to roll back instead of committing.
 *
 * @author Michael Hunger
 * @author Oliver Gierke
 * @since 1.6
 */
public class ChainedTransactionManager implements PlatformTransactionManager {

现在看来,每条消息都在其自己的JMS本地事务中发送。而且这完全不知道您有外部JDBC事务。