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方法落实所有修改