一、目的:在一个程序中,想达到对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 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);