【问题标题】:Is our simultaneous completion of database and JMS processing smart or lucky?我们同时完成数据库和 JMS 处理是聪明还是幸运?
【发布时间】:2018-07-30 01:03:02
【问题描述】:

我们正在使用 JMS 在 Java 1.8 SE 环境中处理消息。消息来自 Oracle (12) 高级队列。

我们想从 JMS 队列中读取一条消息,基于它做一些工作,并将结果保存在数据库中。我们不想丢失任何消息,也不想重复处理任何消息。换句话说,我们希望 JMS 消息和相关数据库活动的处理成为单个事务。

我们已经阅读了有关如何执行此操作的各种文章(包括Transaction and redelivery in JMSJMS Message Delivery Reliability and Acknowledgement PatternsReliable JMS with Transactions)。共识似乎是使用 JTA/XA,但我们希望使用更简单的东西。

我们使用 Oracle 的高级队列作为我们的 JMS 提供程序,因此我们决定看看我们是否可以为 JMS 和数据库活动使用相同的数据库连接,以便单个提交可以同时用于 JMS 和数据库活动。它似乎奏效了。

在下面的代码中,我们在初始化 JMS 队列时使用现有的 SQL 连接创建了一个 QueueConnection。处理完消息后,提交 JMS 会话也会提交数据库更改。 我们还没有看到其他地方讨论过这种方法,所以我们想知道是否

  1. 我们有一个适用于 Oracle Advanced 的可靠解决方案 排队,
  2. 我们有一个解决方案恰好适用于某些 这个版本的 Oracle Advanced Queueing 的时间,
  3. 我们刚刚得到 我们的测试用例真的非常幸运,这种方法令人担忧 有危险

请评论我们的方法是否应该可靠,或者我们是否应该使用 JTA/XA。

public class OracleJmsQueue {

private DataSource dataSource;
protected Queue queue;
protected QueueConnection queueConnection;
protected QueueReceiver queueReceiver;
protected QueueSession queueSession;
private java.sql.Connection dbConnection = null;

protected void initQueueSession()
        throws JMSException, SQLException {
    // Connect to the database source of messages
    DataSource dataSource = getDataSource();
    dbConnection = dataSource.getConnection();
    dbConnection.setAutoCommit(false);
    queueConnection = AQjmsQueueConnectionFactory.createQueueConnection(
            dbConnection);

    queueSession =
            queueConnection.createQueueSession(true, Session.SESSION_TRANSACTED);
    queue = ((AQjmsSession)queueSession).getQueue(queueUser, queueName);
    queueReceiver = queueSession.createReceiver(queue);
}

public void run() {
  initQueueSession();
  // code omitted
  while (!Thread.currentThread().isInterrupted()) {
    try {
        Thread.sleep(200);
        final Message message = queueReceiver.receiveNoWait();
        if (message != null) {
            processMessage(message);  // alters DB tables
            commitSession();
        }
    }
    // catches omitted
  }
}

protected void commitSession() throws JMSException {
    logger.info("Committing " + queueName + " queue session");
    queueSession.commit();
}
}  // class OracleJmsQueue

【问题讨论】:

    标签: oracle jms advanced-queuing


    【解决方案1】:

    看起来您对 JMS 和 OAQ 的假设是正确的,因为 processMessage 使用 dbConnection 类属性。

    https://docs.oracle.com/javaee/7/api/javax/jms/QueueConnection.html

    所以,回答您的问题:是的,您有一个可靠的解决方案(假设我之前提到过)。

    【讨论】:

      猜你喜欢
      • 2013-09-21
      • 2012-07-09
      • 1970-01-01
      • 2016-05-04
      • 2019-05-02
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多