3

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

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

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

当前遵循以下流程:

应用服务器 1:

  • 通过网络服务传入的消息
  • 启动数据库事务
  • 使用 id 将消息保存在数据库中
  • 队列Q1上消息的post id和其他信息
  • 提交事务

应用服务器 2:

  • 相同的设置,水平缩放

要求

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

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

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

我正在使用 Java:

  • 春天 2.5.6
  • 休眠 3.3
  • 事务管理器:org.springframework.orm.hibernate3.HibernateTransactionManager
  • 数据源:oracle.jdbc.pool.OracleDataSource
4

1 回答 1

0

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

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),本地事务将被回滚并且对象不会被持久化。我认为您不需要分布式事务。

于 2013-11-08T20:55:03.263 回答