JavaEE5学习笔记03-JMS介绍与使用---5
? JMS的事务控制
JMS控制消息发送的事务有2种途径,一个是利用Connection接口建立事务性会话,另一个就是利用JTA标准接口控制事务了。
Session事务性会话
??? public void sendMessage() {
?
?????? try {
?????????? String Connection_Factory = "ConnectionFactory";
?
?????????? Context context = getInitialContext();
?
?????????? ConnectionFactory connectionFactory = (ConnectionFactory) context
????????????????? .lookup(Connection_Factory);
?
?????????? Destination dest = (Destination) context.lookup("jbossJMSTopic");
?
?????????? Connection connection = connectionFactory.createConnection();
?
?????????? Session session = connection.createSession(true,
????????????????? Session.CLIENT_ACKNOWLEDGE);
?
?????????? MessageProducer sender = session.createProducer(dest);
?
?????????? sender.setDeliveryMode(DeliveryMode.PERSISTENT);
?????????? // sender.setTimeToLive(2000);
?
?????????? sender.setPriority(9);
?
?????????? TextMessage textMessage = session.createTextMessage();
?
?????????? textMessage.setStringProperty("ConType", "txt");
?
?????????? textMessage.setText("hello 速速");
?
?????????? sender.send(textMessage);
?
?????????? System.out.println("停顿5秒钟");
?
?????????? // 等待50秒
?????????? Thread.sleep(5000);
?
?????????? System.out.println("停顿5秒钟完毕");
?
?????????? textMessage.setText("welcome to JMS");
?
?????????? sender.send(textMessage);
??????????
?????????? //此处抛出运行时异常
?????????? int a = 1/0;
??????????
?????????? session.commit();
?????????? session.close();
?????????? connection.close();
?????? } catch (Exception e) {
?????????? e.printStackTrace();
?????? }
?
??? }
此代码会抛出异常
java.lang.ArithmeticException: / by zero
所以消费者是无法接收到此消息的,因为事务还没有提交呢,就抛出了异常,还有一点就是在建立session的时候如果是建立的事务性会话,必须手工代码让会话提交事务session.commit();消息才能送达到目的地!
JTA管理JMS消息事务
如果需要让JMS、数据库、EJB操作等参与到事务当中,则应该考虑JTA事务。因为Session事务性会话总会打开一个新的事务,在Session中未commit之前,全部都在一个Session事务中,而数据库操作、EJB操作等等不能参与、共享此会话性事务中。所以此时应该用JTA来包装此事务。
来看JTA控制的消息生产者的一个Servlet代码
public void doPost(HttpServletRequest request, HttpServletResponse response)
?????????? throws ServletException, IOException {
?
?????? UserTransaction userTransaction = null;
?????? java.sql.Connection connectionSQL = null;
?????? DataSource dataSource = null;
?
?????? Statement statement = null;
?
?????? Context context;
?????? try {
?????????? context = new InitialContext();
??????????
?????????? dataSource = (DataSource) context.lookup("java:/jbossdemo");
?
?????????? String Connection_Factory = "ConnectionFactory";
?
?????????? ConnectionFactory connectionFactory = (ConnectionFactory) context
????????????????? .lookup(Connection_Factory);
?
?????????? Destination dest = (Destination) context.lookup("jbossJMSTopic");
?
?????????? // 获得JTA相关用户接口
?????????? userTransaction = (UserTransaction) context
????????????????? .lookup("UserTransaction");
?
?????????? // 开始事务
?????????? userTransaction.begin();
?
?????????? javax.jms.Connection connection = connectionFactory.createConnection();
?
?????????? Session session = connection.createSession(false,
????????????????? Session.AUTO_ACKNOWLEDGE);
?
?????????? MessageProducer sender = session.createProducer(dest);
?
?????????? sender.setDeliveryMode(DeliveryMode.PERSISTENT);
?????????? // sender.setTimeToLive(2000);
?
?????????? sender.setPriority(9);
?
?????????? TextMessage textMessage = session.createTextMessage();
?
?????????? textMessage.setStringProperty("ConType", "txt");
?
?????????? textMessage.setText("hello 第一个消息");
?
?????????? sender.send(textMessage);
?
?????????? System.out.println("停顿5秒钟");
?
?????????? // 等待50秒
?????????? Thread.sleep(5000);
?
?????????? System.out.println("停顿5秒钟完毕");
?
?????????? textMessage.setText("welcome to JMS");
?
?????????? sender.send(textMessage);
?
?????????? // 执行插入数据业务
?????????? connectionSQL = dataSource.getConnection();
?
?????????? statement = connectionSQL.createStatement();
?
?????????? String insert1 = "insert into person values(13,'欧阳上智')";
?
?????????? String insert2 = "insert into person values(14,'欧阳尚智')";
?
?????????? statement.executeUpdate(insert1);
?
?????????? statement.executeUpdate(insert2);
?
?????????? int a = 1 / 0;
?
?????????? // 提交JTA事务
?????????? userTransaction.commit();
?
?????????? session.close();
?
?????????? connection.close();
?????? } catch (Exception e) {
?????????? // TODO Auto-generated catch block
?????????? e.printStackTrace();
?????????? try {
????????????? userTransaction.rollback();
?????????? } catch (IllegalStateException e1) {
?????? ?????? // TODO Auto-generated catch block
????????????? e1.printStackTrace();
?????????? } catch (SecurityException e1) {
????????????? // TODO Auto-generated catch block
????????????? e1.printStackTrace();
?????????? } catch (SystemException e1) {
????????????? // TODO Auto-generated catch block
????????????? e1.printStackTrace();
?????????? }
?????? }finally{
?????????? try {
????????????? statement.close();
????????????? connectionSQL.close();
?????????? } catch (SQLException e) {
????????????? // TODO Auto-generated catch block
????????????? e.printStackTrace();
?????????? }
??????????
?????? }
这里要说明的就是此处的上下文因为是在一个J2EE环境下调用的,所以改