Blog信息 |
blog名称: 日志总数:1304 评论数量:2242 留言数量:5 访问次数:7619461 建立时间:2006年5月29日 |

| |
[Apache(jakarta)]在Tomcat中使用JDBC与JTA 软件技术, 电脑与网络
lhwork 发表于 2006/7/5 13:53:06 |
因为需要将项目从IBM WebSphere Application Server移植到Tomcat上开发,所以研究了一下在Tomcat中通过JNDI查找和使用JDBC及JTA的方法。
Tomcat是Servlet容器,但它也提供了一个JNDI
InitialContext实现,因此用户可以像在J2EE应用程序服务器中一样在Tomcat中使用JNDI查找JDBC数据源。不过在事务处理方
面,Tomcat本身并不支持JTA(Java Transaction API),所以需要借助其他的方案。JOTM(Java Open Transaction Manager)是ObjectWeb的一个开源JTA实现,它本身也是开源应用程序服务器JOnAS(Java Open Application Server)的一部分,为其提供JTA支持和分布式事务管理。JOTM同样可以为Tomcat提供JTA支持,以下将对相关的配置进行简单说明,使用的相应版本为: Tomcat 5.5.xJOTM 2.0.xOracle 9i 1. 配置Tomcat环境
在$TOMCAT_HOME/conf/context.xml文件中添加以下内容:
<Resource name="jdbc/framework" auth="Container" type="javax.sql.DataSource" factory="org.objectweb.jndi.DataSourceFactory" username="user" password="pwd" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@172.18.136.200:1521:ORADB" maxActive="30" maxIdle="30"/> <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/> 2. 添加所需的JAR文件
下载JOTM,将以下文件添加到$TOMCAT_HOME/common/lib/: jotm.jar jotm_jrmp_stubs.jar jotm_iiop_stubs.jar ow_carol.jar jta-spec1_0_1.jar jts1_0.jar objectweb-datasource.jar xapool.jar howl.jar connector-1_5.jar 同时,还需要添加相应数据库的JDBC包,例如Oracle的classes12.jar 3. 配置JOTM
新建一个carol.properties文件,置于$TOMCAT_HOME/common/classes/,文件内容如下: # JNDI (Protocol Invocation) carol.protocols=jrmp # Local RMI Invocation carol.jvm.rmi.local.call=true # do not use CAROL JNDI wrapper carol.start.jndi=false # do not start a name server carol.start.ns=false # Naming Factory carol.jndi.java.naming.factory.url.pkgs=org.apache.naming 这样JOTM将不会使用CAROL JNDI wrapper,从而可以避免类装载错误的发生
4. 说明
4.1 JOTM目前的版本在JDK1.5或以上可能无法正常运行,解决的方法有两个:使用JDK1.5重新编译carol库,或者将Tomcat运行在JDK1.4中
4.2 <Transaction>是Tomcat 5中的新标记,对于不支持此标记的老版本,需要使用以下语句代替事务资源的声明:
<!-- Resource configuration for UserTransaction use JOTM --> <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction" factory = "org.objectweb.jotm.UserTransactionFactory" jotm.timeout = "60"/>
4.3
需要注意的是,使用<Resource>节点声明的资源默认上下文前缀是"java:comp/env",而使用<
Transaction>节点时则是"java:comp"。因此,当使用4.2的方式声明用户事务时,相应的JNDI查找代码也应该改为
UserTransaction ut = (UserTransaction)initCtx.lookup("java:comp/env/UserTransaction"); 5. 测试 假设数据库中已经做了相应配置,可以使用如下jsp页面进行测试: <!--test.jsp--> <%@page contentType="text/html;charset=GB2312"%> <%@page import="java.sql.*"%> <%@page import="javax.sql.*"%> <%@page import="javax.naming.*"%> <%@page import="javax.transaction.UserTransaction"%> <% ResultSet rs = null; Statement stmt = null; UserTransaction ut = null; Connection conn = null; try { Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("jdbc/framework"); ut = (UserTransaction)initCtx.lookup("java:comp/UserTransaction"); conn = ds.getConnection(); ut.begin(); System.out.println("<<< beginning the transaction >>>"); stmt = conn.createStatement( // ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); rs = stmt.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); rs.next(); } catch(Exception e) {e.printStackTrace();} %> <html> <body> Original price: <%=rs.getString("price")%> <br>After update: <% PreparedStatement pstmt = conn.prepareStatement("update tm_product set price=? where id=1"); pstmt.setInt(1,101); pstmt.executeUpdate(); rs = stmt.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); rs.next(); %> <%=rs.getString("price")%> <br>After Rollback: <% System.out.println("<<< rolling back the transaction >>>"); ut.rollback();//Or ut.commit(); rs = stmt.executeQuery("SELECT PRICE FROM TM_PRODUCT WHERE ID=1"); rs.next(); %> <%=rs.getString("price")%> <%conn.close();%> </body> </html>
6. 参考 How to use JDBC and transactions in Tomcat with JOTM How to use JDBC and transactions in Tomcat with JOTM(For Tomcat 5.5.x) UserTransaction, JOTM and Tomcat 5.5.x |
|
|