java jta mysql_在Tomcat中使用JDBC与JTA

因为需要将项目从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.x

JOTM 2.0.x

Oracle 9i

1. 配置Tomcat环境

在$TOMCAT_HOME/conf/context.xml文件中添加以下内容:

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"/>

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 是Tomcat 5中的新标记,对于不支持此标记的老版本,需要使用以下语句代替事务资源的声明:

type="javax.transaction.UserTransaction"

factory = "org.objectweb.jotm.UserTransactionFactory"

jotm.timeout = "60"/>

4.3 需要注意的是,使用节点声明的资源默认上下文前缀是"java:comp/env",而使用< Transaction>节点时则是"java:comp"。因此,当使用4.2的方式声明用户事务时,相应的JNDI查找代码也应该改为 UserTransaction ut = (UserTransaction)initCtx.lookup("java:comp/env/UserTransaction");

5. 测试

假设数据库中已经做了相应配置,可以使用如下jsp页面进行测试:

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();}

%>

Original price:


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();

%>


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();

%>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用JTA/JTS和JDBC的主要区别在于事务管理。使用JTA/JTS可以更方便地管理事务,尤其是对于分布式应用程序,JTA/JTS可以帮助协调多个事务管理器之间的事务。而使用JDBC进行事务管理则需要手动控制事务的提交和回滚,比较繁琐。 下面是一个使用JDBC进行事务管理的代码示例: ```java import java.sql.*; public class JdbcExample { public void doTransaction() throws SQLException { Connection conn = null; try { // 获取数据库连接,并设置自动提交为false conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "username", "password"); conn.setAutoCommit(false); // 执行SQL语句 PreparedStatement pstmt = conn.prepareStatement("INSERT INTO mytable VALUES (?, ?)"); pstmt.setInt(1, 1); pstmt.setString(2, "test"); pstmt.executeUpdate(); // 提交事务 conn.commit(); } catch (SQLException e) { // 回滚事务 if (conn != null) { conn.rollback(); } throw e; } finally { // 关闭数据库连接 if (conn != null) { conn.close(); } } } } ``` 在上面的代码,我们使用JDBC获取数据库连接,并将其自动提交设置为false。然后我们执行SQL语句,如果出现异常,我们将回滚事务。最后我们关闭数据库连接。 下面是一个使用JTA/JTS进行事务管理的代码示例: ```java import javax.transaction.UserTransaction; import javax.transaction.TransactionManager; import javax.transaction.Transaction; import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.*; public class JtaJtsExample { public void doTransaction() throws Exception { // 获取UserTransaction和TransactionManager UserTransaction tx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); TransactionManager tm = (TransactionManager) new InitialContext().lookup("java:appserver/TransactionManager"); // 开始事务 tx.begin(); try { // 获取数据源 DataSource ds = (DataSource) new InitialContext().lookup("java:app/jdbc/mydatasource"); // 获取数据库连接,并设置自动提交为false Connection conn = ds.getConnection(); conn.setAutoCommit(false); // 执行SQL语句 PreparedStatement pstmt = conn.prepareStatement("INSERT INTO mytable VALUES (?, ?)"); pstmt.setInt(1, 1); pstmt.setString(2, "test"); pstmt.executeUpdate(); // 提交事务 conn.commit(); tx.commit(); } catch (Exception e) { // 回滚事务 tx.rollback(); throw e; } } } ``` 在上面的代码,我们使用JTA/JTS获取UserTransaction和TransactionManager的实例,然后开始事务并获取数据源。在执行SQL语句之前,我们将数据库连接的自动提交设置为false,以便我们可以在事务控制提交和回滚。当我们执行完SQL语句后,我们提交事务并关闭数据库连接。如果出现任何异常,我们将回滚事务并抛出异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值