繁体   English   中英

spring boot xa transaction datasource和jms

[英]spring boot xa transaction datasource and jms

我使用spring-boot-starter-data-jpa和spring-boot-starter-activemq创建了一个POC。 我想在提交jpa事务时在代理(activeMQ)上推送jms消息。

我的代码:UtilsateurService有“主要”交易:

@Service
public class UtilisateurService {

    @Autowired
    private UtilisateurRepository utilisateurRepository;

    @Autowired
    private SendMessage sendMessage;

    @Transactional(rollbackOn = java.lang.Exception.class)
    public Utilisateur create(Utilisateur utilisateur) throws Exception {
        final Utilisateur result = utilisateurRepository.save(utilisateur);
        sendMessage.send("creation utilisateur : " + result.getId());
        throw new Exception("rollback");
        //return result;
    }
}

SendMessage类巫婆“管理”Jms消息:

@Component
public class SendMessage {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Value("${jms.queue.destination}")
    private String destinationQueue;

    public void send(String msg) {
        this.jmsMessagingTemplate.convertAndSend(destinationQueue, msg);
    }

}

我的主要课程:

@SpringBootApplication
@EnableJms
@EnableTransactionManagement
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

在抛出异常之前,JMS消息是在activeMq代理上推送的。 所以我没有经纪人“回滚”。

如何配置让xa事务运行?

是你的jmsTemplate交易?

jmsTemplate.setSessionTransacted(true); 

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted-boolean-

public void setSessionTransacted(boolean sessionTransacted)

设置创建JMS会话时使用的事务模式。 默认为“false”。 请注意,在JTA事务中,不考虑传递给create(Queue / Topic)Session(boolean transacted,int acknowledgeMode)方法的参数。 根据Java EE事务上下文,容器会自行决定这些值。 类似地,在本地管理的事务中也不考虑这些参数,因为在这种情况下访问者在现有的JMS会话上操作。

将此标志设置为“true”将在托管事务外部运行时使用短本地JMS事务,并且在托管事务(XA事务除外)存在时使用同步本地JMS事务。 这具有本地JMS事务与主事务(可能是本机JDBC事务)一起管理的效果,JMS事务在主事务之后立即提交。

http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

30.2.5交易管理

Spring提供了一个JmsTransactionManager来管理单个JMS ConnectionFactory的事务。 这允许JMS应用程序利用Spring的托管事务功能,如第17章“事务管理”中所述。 JmsTransactionManager执行本地资源事务,将JMS连接/会话对从指定的ConnectionFactory绑定到线程。 JmsTemplate会自动检测此类事务资源并对其进行相应操作。

在Java EE环境中,ConnectionFactory将池连接和会话,因此这些资源可以跨事务有效地重用。 在独立环境中,使用Spring的SingleConnectionFactory将导致共享JMS连接,每个事务都有自己独立的Session。 或者,考虑使用特定于提供者的池适配器,例如ActiveMQ的PooledConnectionFactory类。

JmsTemplate还可以与JtaTransactionManager和支持XA的JMS ConnectionFactory一起使用,以执行分布式事务。 请注意,这需要使用JTA事务管理器以及正确配置XA的ConnectionFactory! (查看Java EE服务器的/ JMS提供程序的文档。)

使用JMS API从Connection创建会话时,在托管和非托管事务环境中重用代码可能会造成混淆。 这是因为JMS API只有一个工厂方法来创建会话,它需要事务和确认模式的值。 在托管环境中,设置这些值是环境的事务基础结构的责任,因此供应商的JMS连接包装器会忽略这些值。 在非托管环境中使用JmsTemplate时,可以通过使用属性sessionTransacted和sessionAcknowledgeMode来指定这些值。 将PlatformTransactionManager与JmsTemplate一起使用时,将始终为模板提供事务性JMS会话。

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html#jms-tx

哈森给出了解决方案。 所以我将SendMessage类更改为:

@Component
public class SendMessage {

    private final JmsMessagingTemplate jmsMessagingTemplate;

    @Value("${jms.queue.destination}")
    private String destinationQueue;

    @Autowired
    public SendMessage(JmsMessagingTemplate jmsMessagingTemplate) {
        this.jmsMessagingTemplate = jmsMessagingTemplate;
        this.jmsMessagingTemplate.getJmsTemplate().setSessionTransacted(true);
    }

    public void send(String msg) {
        this.jmsMessagingTemplate.convertAndSend(destinationQueue, msg);
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM