0

我的目标是使用 Bitronix 交易,我应该使用两种资源:

  1. 数据库
  2. 管理系统

我有以下java代码:

package com.mycompany.app;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;

import javax.annotation.Resource;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.QueueReceiver;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.transaction.Transaction;
import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.jta.JtaTransactionManager;

import bitronix.tm.BitronixTransactionManager;
import bitronix.tm.TransactionManagerServices;

public class JMSExample {

    static String serverUrl = "tcp://localhost:61616"; // values changed
    static String userName = "admin";
    static String password = "admin";

    static TextMessage message;

    public static void sendTopicMessage(String topicName, String messageStr) {

        Connection connection = null;

        try {
            BitronixTransactionManager btm = TransactionManagerServices.getTransactionManager();
            btm.begin();
            System.out.println("Publishing to destination '" + topicName + "'\n");
            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(serverUrl);
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            Queue queue = session.createQueue(topicName);
            Message msg = session.createTextMessage(messageStr);
            msg.setJMSCorrelationID("correlationID1");
            MessageProducer producer = session.createProducer(queue);
            producer.send(msg);
            System.out.println("Published message: " + messageStr);
            session.commit();
            session.close();
            connection.close();
            btm.rollback();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        JMSExample.sendTopicMessage("test", "Hi");
    }
}

当我运行上述程序时,我能够看到队列中的消息。但我希望 JMS 事务与 Bitronix 事务一起嵌套。换句话说,如果 Bitronix 回滚,队列中也不应该有任何消息。

4

2 回答 2

0

在 btm.rollback() 完成工作时删除 session.commit()

于 2019-12-13T18:56:34.943 回答
0

如果您想在事务中以原子方式使用 2 个资源,那么您需要javax.transaction.xa.XAResource从每个资源管理器(即 JMS 代理和数据库)获取实现。一旦你有了这些,你就可以让他们加入你从事务管理器开始的 JTA 事务中。然后将使用登记的 XA 资源自动执行任何提交或回滚。

要从XAResourceJMS 中获取信息,请查看javax.jms.XAConnectionFactory. 您可以使用createXAConnection()获取一个实例,javax.jms.XAConnection然后使用createXASession()获取一个javax.jms.XASession,最后使用getXAResource().

要从XAResourceJDBC 中获取,请查看javax.sql.XADataSource. 您可以使用getXAConnection()获取一个实例,javax.sql.XAConnection然后使用getXAResource().

然后您可以调用getTransaction()事务管理器并使用返回javax.transaction.Transaction的调用enlistResource()您的 XAResources。然后,当您调用commit()rollback()事务管理器将处理您的所有XAResource实现并确保一切都以原子方式执行。

于 2019-12-13T19:14:49.300 回答