ActiveMQ 分布式事务+伸缩

Posted

技术标签:

【中文标题】ActiveMQ 分布式事务+伸缩【英文标题】:ActiveMQ distributed transaction + scaling 【发布时间】:2013-11-20 12:04:37 【问题描述】:

我目前正在使用 Oracle AQ,并希望将其替换为持久的 ActiveMQ。

我目前使用 Oracle AQ 的设置是:

数据库服务器:带有队列 Q1 的 Oracle 数据库 应用服务器 1:第一季度有一个生产者和多个监听器 应用服务器 2:在 Q1 上有一个生产者和多个侦听器

目前遵循以下流程:

应用服务器 1:

通过网络服务传入的消息 启动数据库事务 用 id 将消息保存在数据库中 队列Q1消息的post id等信息 提交交易

应用服务器 2:

相同的设置,水平缩放

要求

在实现 ActiveMQ 时,我希望将数据发送到数据库并在同一事务中发送到队列中。因此,如果一个人回滚,另一个人也会这样做。

因为我需要能够同时在两个应用服务器的队列上生成消息,所以我需要在 DB 服务器上而不是在应用服务器上运行 ActiveMQ 代理。否则它们将充当“主从”。

我阅读了article,他们解释了如何共享事务资源。 但这是假设您将 ActiveMQ 代理放在与事务启动的服务器相同的服务器上。 有没有什么办法,除了使用JTA来完成这个吗?

我正在使用 Java:

春季 2.5.6 休眠 3.3 TransactionManager:org.springframework.orm.hibernate3.HibernateTransactionManager 数据源:oracle.jdbc.pool.OracleDataSource

【问题讨论】:

【参考方案1】:

我没有测试这个。但这不是您要找的吗?

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SomeServiceImpl implements SomeService 

    @Autowired
    private Queue someQueue;

    private JmsTemplate jmsTemplate;
    private SomeRepository repository;

    public SomeServiceImpl() 

    public SomeServiceImpl(ConnectionFactory activeMQConnectionFactory, SomeRepository repository) 
        this.jmsTemplate = new JmsTemplate(activeMQConnectionFactory);
        this.repository = repository;
    

    @Transactional(rollbackFor = JmsException.class, RepositoryException.class)
    public void sendMessage(final SomeObject object) 
        repository.save(object);
        jmsTemplate.send(       
        new MessageCreator()           
            @Override
            public Message createMessage(Session session) throws JMSException 
                return session.createObjectMessage(object.getSpecialId());
            
        );
    


这样,如果在保存对象时出现故障或将消息发送到队列时出现问题(JMSException),本地事务将被回滚并且对象不会被持久化。我认为您不需要分布式事务。

【讨论】:

以上是关于ActiveMQ 分布式事务+伸缩的主要内容,如果未能解决你的问题,请参考以下文章

高并发分布式消息中间件技术ActiveMQ事务

高并发分布式消息中间件技术ActiveMQ事务

基于 HBase 构建可伸缩的分布式事务队列

浅析超越分布式事务的方法—— 一个叛逆者的观点

大型电商分布式网站架构设计与实践,Java分布式架构,Java事务分布式高并发-视频教程

分布式事务两阶段提交协议三阶提交协议