技术开发 频道

漫谈WebSphere应用服务器之事务

3. WebSphere事务

    WAS作为一个J2EE服务器,自然也就实现了JTS跟JTA。这儿再温习一下整个事务的一个完整的运作过程.。这儿我们使用如下的一个场景:应用在完成一个业务时需要同时访问数据库和消息系统,而且需要保证对这两种资源的更新的事务性,这儿应用使用了userTransaction来自己控制事务。示例代码如下:

    InitialContext ic = new InitialContext();
        DataSource ds = (DataSource) ic.lookup("jdbc/order");
        ConnectionFactory connectionFactory =
            (ConnectionFactory)ic.lookup("jms/orderCF");

        UserTransaction ut = (UserTransaction) ic.lookup("java:comp/UserTransaction");
      
        try{
          
            ut.begin();
          
            javax.jms.Connection jmsConnection = connectionFactory.createConnection();
            Session session = jmsConnection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            Queue sendQueue = (Queue) ic.lookup("jms/orderQueue");
            MessageProducer producer = session.createProducer(sendQueue);
            jmsConnection.start();
            TextMessage requestMessage = session.createTextMessage("data");
            producer.send(requestMessage);

            session.close();
            jmsConnection.close();
          
          
            java.sql.Connection jdbcConnection = ds.getConnection();
            java.sql.Statement st = jdbcConnection.createStatement();
            String sql = "insert into ...";
            st.execute(sql);
          
            st.close();
            jdbcConnection.close();
          
            ut.commit();
        }catch(Exception e) {
            try {
                ut.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();
            }
        }

    我们可以用下面的两幅图来分析整个事务的处理过程。

    首先看一下这两个资源是如何注册到事务管理器中的。

    (1) 应用通过userTransaction.begin()开始事务。JTS把创建事务并把它关联到当前的线程上。

    (2) 用户执行JDBC操作:拿到数据源、连接、创建Statement,最后调用statement.execute来执行sql语句来在数据库中创建一条新条目。

    (3) 因为这儿使用的statement是经过容器包装的一个Wrapper,在其实现中首先向真正的XAConnection拿到XAResource。

    (4) 然后调用transactionManager.getTransaction().enlistResource()方法来把该XAResource加入到当前事务中。

    (5) 事务管理器调用该XAResource的start方法来通知资源管理器开始记录事务性操作。

    (6) 最后调用真正的Statement的execute()方法来执行数据库操作。

    7到11步和上述类似。通过类似的操作把JMS资源加到当前的事务中。

    当业务步骤完成后,调用close来关闭连接,然后调用commit来提交事务。这些操作都会触发对应的XA的动作,如下所示:

    (12) 当connection的close方法被调用到后

    (13) 容器提供的Connection wrapper会先调用transactionManager.getTransaction().delistResource()方法来停止记录。

    (14) JTS调用XAResouce的end方法来结束事务。

    (15) 真正的connection的close方法被调用,资源管理器释放资源。

    16到19步完成JMS的close操作。

    (20) 然后userTransaction的commit被调用,此时开始两阶段提交。

    (21) 首先JTS向JDBC的XAResource发起prepare请求,如果返回Prepared,则

    (22) JTS向JMS的XAResource发起prepare请求,如果还是返回Prepared,则

    (23) 调用JDBC的XAResource的commit方法落实所有修改

    (24) 调用JMS的XAResource的commit方法落实所有修改

0
相关文章