| 
 | 
	
 
 
  一、目的:在一个程序中,想达到对oracle数据库与sql server2000数据库的操作通过一个事务来管理,一起提交一起回滚,需要用到JTA。 
  参考文档:http://www.blogjava.net/zhanglijun33/archive/2006/09/21/jta.html 
  二、下面说下我的具体实现: 
  1、JOTM包: 
  下载地址:http://jotm.ow2.org/xwiki/bin/view/Main/Download_Releases 
  我用的是ow2-jotm-dist-2.1.9-bin,由于我使用的是比较新的JOTM版本,所以不需要考虑参考文档中4.1提到的问题。 
  2、tomcat环境: 
  (1)版本:5.5.26 
  (2)commons\lib:把ow2-jotm-dist-2.1.9\lib中的包都放进来。 
  (3)context.xml: 
  <Context> 
  ...... 
  <Resource name="jdbc/orcldb"  
auth="Container" 
type="javax.sql.DataSource"  
factory="org.objectweb.jotm.datasource.DataSourceFactory" 
driverClassName="oracle.jdbc.driver.OracleDriver" 
username="bt_dyw" password="bt_dyw" 
url="jdbc:oracle:thin:@localhost:1521:orcl"/> 
  <Resource name="jdbc/sqldb"  
auth="Container" 
type="javax.sql.DataSource"  
factory="org.objectweb.jotm.datasource.DataSourceFactory" 
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver" 
username="sa" password="sa" 
url="jdbc:microsoft:sqlserver://BJ152:1433;DataBaseName=bt_jszx;SelectMethod=cursor"/> 
  <Resource name="UserTransaction"  
            auth="Container"  
            type="javax.transaction.UserTransaction" /> 
  <Transaction factory="org.objectweb.jotm.UserTransactionFactory" 
jotm.timeout="60"/> 
  ...... 
  </Context> 
  4、web应用中的代码: 
  index.jsp: 
 
 
<%@page contentType="text/html;charset=GB2312"%> 
<%@page import="java.sql.*"%> 
<%@page import="javax.sql.*"%> 
<%@page import="javax.naming.*"%> 
<%@page import="javax.transaction.UserTransaction"%> 
<% 
Connection connOracle = null; 
Statement stmtOracle = null; 
ResultSet rsOracle = null; 
Connection connSql = null; 
Statement stmtSql = null; 
ResultSet rsSql = null; 
UserTransaction ut = null; 
try { 
    Context initCtx = new InitialContext(); 
    Context envCtx = (Context) initCtx.lookup("java:comp/env"); 
    DataSource dsOracle = (DataSource) envCtx.lookup("jdbc/orcldb"); 
    DataSource dsSql = (DataSource) envCtx.lookup("jdbc/sqldb"); 
    ut = (UserTransaction)initCtx.lookup("java:comp/UserTransaction"); 
    connOracle = dsOracle.getConnection(); 
    connSql = dsSql.getConnection(); 
    ut.begin(); 
    System.out.println("<<< beginning the transaction >>>"); 
     
    stmtOracle = connOracle.createStatement( 
    // ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE 
    ); 
    rsOracle = stmtOracle.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
    rsOracle.next(); 
    stmtSql = connSql.createStatement( 
    // ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE 
    ); 
    rsSql = stmtSql.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
    rsSql.next(); 
} catch(Exception e) { 
    e.printStackTrace(); 
} 
%> 
<html> 
<body> 
Original price Oracle: 
<%=rsOracle.getString("price")%> 
<br />Original price Sql: 
<%=rsSql.getString("price")%> 
<br />After update Oracle: 
<% 
PreparedStatement pstmtOracle = connOracle.prepareStatement("update tm_product set price=? where id=1"); 
pstmtOracle.setInt(1,101); 
pstmtOracle.executeUpdate(); 
rsOracle = stmtOracle.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
rsOracle.next(); 
%> 
<%=rsOracle.getString("price")%> 
<br />After update Sql: 
<% 
PreparedStatement pstmtSql = connSql.prepareStatement("update tm_product set price=? where id=1"); 
pstmtSql.setInt(1,101); 
pstmtSql.executeUpdate(); 
rsSql = stmtSql.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
rsSql.next(); 
%> 
<%=rsSql.getString("price")%> 
<% 
System.out.println("<<< rolling back the transaction >>>"); 
ut.rollback();//Or ut.commit(); 
%> 
<br />After Rollback Oracle: 
<% 
rsOracle = stmtOracle.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
rsOracle.next(); 
%> 
<%=rsOracle.getString("price")%> 
<%connOracle.close();%> 
<br />After Rollback Sql: 
<% 
rsSql = stmtSql.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); 
rsSql.next(); 
%> 
<%=rsSql.getString("price")%> 
<%connSql.close();%> 
</body> 
</html>  5、测试用数据的准备 
  oracle中: 
  create table tm_product(id number(9) primary key,price number(9)); 
  insert into tm_product values(1,1200); 
  commit; 
  sql server2000中: 
  create table tm_product(id numeric(9) primary key,price numeric(9)); 
  insert into tm_product values(1,1500); 
  6、异常处理 
  (1)java.lang.ClassCastException: org.objectweb.jotm.Current 
  我的应用Lib中的jta.jar冲突,去掉后OK 
  (2)java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Can't start a cloned connection while in manual transaction mode. 
  参考:http://blog.sina.com.cn/s/blog_4ffb1bf201009ld3.html 
  7、页面结果展示 
  Original price Oracle: 1200  
Original price Sql: 1500  
After update Oracle: 101  
After update Sql: 101  
After Rollback Oracle: 1200  
After Rollback Sql: 1500  
   
  ps: 
  ut的timeout设置: 
  ut.setTransactionTimeout(3600*5); |   
 
 
 
 | 
  
 |