Spring 在单个事务中更新数据库并发送JMS消息?

Spring 在单个事务中更新数据库并发送JMS消息?,spring,jdbc,transactions,jms,Spring,Jdbc,Transactions,Jms,我使用Spring的DataSourceTransactionManager进行事务管理,使用JmsTemplate向ActiveMQ队列发送消息。我的问题是单事务强制工作下一个算法: Step 1: update DB; Step 2: send message to queue; Step 3: update DB; Step 4: send message to queue. 正如我从JmsTemplate的文档中了解到的,在我的例子中,我必须将参数“sessionTransacted”

我使用Spring的DataSourceTransactionManager进行事务管理,使用JmsTemplate向ActiveMQ队列发送消息。我的问题是单事务强制工作下一个算法:

Step 1: update DB;
Step 2: send message to queue;
Step 3: update DB;
Step 4: send message to queue.
正如我从JmsTemplate的文档中了解到的,在我的例子中,我必须将参数“sessionTransacted”=true: 将此标志设置为“true”将在托管事务外部运行时使用短本地JMS事务,如果存在托管事务(XA事务除外),则使用同步本地JMS事务后者的效果是,本地JMS事务与主事务(可能是本机JDBC事务)一起管理,JMS事务在主事务之后提交。(c)

我的jms配置文件仅包含以下内容:

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" ref="url"/>
        <property name="userName" ref="username"/>
        <property name="password" ref="password"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="defaultDestinationName" value="SomeQueue"/>
        <property name="sessionTransacted" value="true"/>
</bean>

之后,我尝试用简单的方法测试它:

案例A:

@Transactional
public void sendMessageTransactionalErr(Object message, List<String> queueDestinationNames) throws Exception {
    sender.sendMessage(message, queueDestinationNames);
    throw new Exception("FatalException!");
}
@Transactional
public void sendMessageTransactionalErr(对象消息,列表queueDestinationNames)引发异常{
sender.sendMessage(消息,queueDestinationNames);
抛出新异常(“FatalException!”);
}
案例B:

@Transactional
public void sendMessageTransactionalOK(Object message, List<String> queueDestinationNames) throws Exception {
    sender.sendMessage(message, queueDestinationNames);
}
@Transactional
public void sendMessageTransactionalOK(对象消息,列表queueDestinationNames)引发异常{
sender.sendMessage(消息,queueDestinationNames);
}
但在这两种情况下,请求执行后消息都被发送到队列。即使JDBC事务回滚,JMS事务提交也会成功。
我应该怎么做才能使它按我的需要工作?

您需要使用一个事务管理器来处理JMS事务和数据库事务。JMS事务与数据库事务是分开的

我记得不太清楚,但是当我遇到这个问题时,我创建了一个
org.springframework.jms.connection.JmsTransactionManager
的实例。创建一个JTA事务管理器,并确保您的it部门了解该事务管理器和数据库事务管理器。 对注释使用
@Transactional(“jtaTransactionManager”)
。对于这个用例,我可能尝试过Bitronix或JOTM

参考: