程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> jta-為什麼在JMS中使用JTA事務控制全局事務失效

jta-為什麼在JMS中使用JTA事務控制全局事務失效

編輯:編程綜合問答
為什麼在JMS中使用JTA事務控制全局事務失效

package cn.producer;

import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

public class ExceptionMessageSender {
/**

  • 本地獲取Context
  • 需要添加wlclient.jar , webservices.jar , wljmsclient.jar
  • @return */ private Context getInitialContext(){ Context context = null; final String INIT_FACTORY = "weblogic.jndi.WLInitialContextFactory"; final String SERVER_URL = "t3://localhost:7001"; Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, INIT_FACTORY); props.put(Context.PROVIDER_URL, SERVER_URL); try { context = new InitialContext(props); } catch (NamingException e) { e.printStackTrace(); } return context; }

public void sendMessage() throws NamingException, JMSException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException{
//定義默認的weblogic的JNDI
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
//獲取Context
Context context = getInitialContext();
//獲取連接工廠
ConnectionFactory cf = (ConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI);
//獲取連接
Connection conn = cf.createConnection();
//監聽JMS服務器異常情況(只有當JMS服務器運行時發生的異常才會觸發異常監聽器)
conn.setExceptionListener(new ExceptionListener(){
@Override
public void onException(JMSException e) {
System.out.println("JMS服務器發生異常,異常信息如下:");
e.printStackTrace();
}
});
//獲取JTA事務
UserTransaction tx = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
tx.begin();
//獲取會話,如果設置為事務性會話,那麼JTA不起作用
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//獲取消息目的
Destination dest = (Destination) context.lookup("MessageQueue");
//通過會話獲取消息生產者
MessageProducer sender = session.createProducer(dest);
//通過會話創建一個空格JMS消息
TextMessage msg = session.createTextMessage();
msg.setText("你好,我是路人甲!");
//通過消息生產者發送消息
sender.send(msg);
try{
int num = 4/0;//-----------這裡會拋出異常,引發JTA全局事務回滾
msg.setText(num+":number");
sender.send(msg);
tx.commit();
}catch(Exception e){
tx.rollback();
}finally{
//關閉資源
session.close();
conn.close();
}

}
}

package cn.consumer;

import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

public class ExceptionConsumer {
/**

  • 本地獲取Context
  • 需要添加wlclient.jar , webservices.jar , wljmsclient.jar
  • @return */ private Context getInitialContext(){ Context context = null; final String INIT_FACTORY = "weblogic.jndi.WLInitialContextFactory"; final String SERVER_URL = "t3://localhost:7001"; Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, INIT_FACTORY); props.put(Context.PROVIDER_URL, SERVER_URL); try { context = new InitialContext(props); } catch (NamingException e) { e.printStackTrace(); } return context; }

public void receiveMessage() throws NamingException, JMSException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException{
//定義默認的weblogic連接工程的JNDI
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
//獲取Context
Context context = getInitialContext();
//通過JNDI獲取連接工廠
ConnectionFactory cf = (ConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI);
//通過連接工廠獲取連接
Connection conn = cf.createConnection();
//開始JMS傳輸
conn.start();
//設置異常監聽器,監聽JMS服務器上的異常
conn.setExceptionListener(new ExceptionListener(){
public void onException(JMSException e){
System.out.println("JMS服務器發生異常,異常信息如下:");
e.printStackTrace();
}
});
//打開全局事務
UserTransaction tx = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
tx.begin();
//通過連接獲取會話,使用全局事務了,就不應該設置為事務性會話,否則全局事務會失效,使用的事務還是事務性會話的事務
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//獲取消息目的(消息隊列)
Destination dest = (Destination) context.lookup("MessageQueue");
//創建消息消費者
MessageConsumer receiver = session.createConsumer(dest);
//消息消費者同步接收消息
TextMessage msg = (TextMessage) receiver.receiveNoWait();
System.out.println(msg);
if(msg != null){
System.out.println("同步接收到信息:"+msg.getText());
}
//確認事務
tx.commit();
//關閉資源
session.close();
conn.close();
}
}

package cn.test;

import javax.jms.JMSException;
import javax.naming.NamingException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

import cn.producer.ExceptionMessageSender;

public class TestExceptionProducer {
public static void main(String[] args) {
ExceptionMessageSender ems = new ExceptionMessageSender();
try {
ems.sendMessage();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
} catch (NotSupportedException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
} catch (RollbackException e) {
e.printStackTrace();
} catch (HeuristicMixedException e) {
e.printStackTrace();
} catch (HeuristicRollbackException e) {
e.printStackTrace();
}
}
}


代碼貼在上面,我的意思就是不用JMS自帶的事務,而用JTA來控制全局事務。但是沒找到失效的原因。

最佳回答:


終於被我搞清楚了,原來是Connection和ConnectionFactory的問題。Connection是不支持JTA全局事務的,要用weblogic.jms.XAConnetion,
而XAConnection通過weblogic.jms.XAConnetionFactory獲取。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved