Bitronix 事务不适用于 JMS 队列
Bitronix Transaction not working with JMS queue
我有一个 objective 使用 Bitronix 事务,我应该使用两个资源:
- 数据库
- JMS
我有以下 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 回滚,队列中也不应该有任何消息。
删除 session.commit() 而 btm.rollback() 完成工作
如果您想在一个事务中以原子方式处理 2 个资源,那么您需要从每个资源管理器(即 JMS 代理和数据库)获取 javax.transaction.xa.XAResource
实现。一旦您拥有了这些,您就可以将它们登记到您使用事务管理器启动的 JTA 事务中。然后任何提交或回滚都将使用登记的 XA 资源自动执行。
要从 JMS 获取 XAResource
,请查看 javax.jms.XAConnectionFactory
. You can use createXAConnection()
to get an instance of javax.jms.XAConnection
and then use createXASession()
to get an javax.jms.XASession
,然后最后使用 getXAResource()
。
要从 JDBC 获得 XAResource
,请查看 javax.sql.XADataSource
. You can use getXAConnection()
to get an instance of javax.sql.XAConnection
,然后使用 getXAResource()
。
然后您可以使用您的 XAResources 调用 getTransaction()
on the transaction manager and use the returned javax.transaction.Transaction
to invoke enlistResource()
。然后,当您调用 commit()
或 rollback()
时,事务管理器将处理您所有的 XAResource
实现,并确保一切都以原子方式执行。
我有一个 objective 使用 Bitronix 事务,我应该使用两个资源:
- 数据库
- JMS
我有以下 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 回滚,队列中也不应该有任何消息。
删除 session.commit() 而 btm.rollback() 完成工作
如果您想在一个事务中以原子方式处理 2 个资源,那么您需要从每个资源管理器(即 JMS 代理和数据库)获取 javax.transaction.xa.XAResource
实现。一旦您拥有了这些,您就可以将它们登记到您使用事务管理器启动的 JTA 事务中。然后任何提交或回滚都将使用登记的 XA 资源自动执行。
要从 JMS 获取 XAResource
,请查看 javax.jms.XAConnectionFactory
. You can use createXAConnection()
to get an instance of javax.jms.XAConnection
and then use createXASession()
to get an javax.jms.XASession
,然后最后使用 getXAResource()
。
要从 JDBC 获得 XAResource
,请查看 javax.sql.XADataSource
. You can use getXAConnection()
to get an instance of javax.sql.XAConnection
,然后使用 getXAResource()
。
然后您可以使用您的 XAResources 调用 getTransaction()
on the transaction manager and use the returned javax.transaction.Transaction
to invoke enlistResource()
。然后,当您调用 commit()
或 rollback()
时,事务管理器将处理您所有的 XAResource
实现,并确保一切都以原子方式执行。