应用程序有了UserTransaction对象的引用之后,就可以象示例5那样来起动事务。
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("UPDATE MOVIES ...");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
// ...
utx.commit();
// ...
当应用程序调用commit()时,事务管理器使用两段提交协议来结束事务。
JTA事务控制的方法
.javax.transaction.UserTransaction接口提供了下列事务控制方法:
.public void begin()
.public void commit()
.public void rollback()
.public void getStatus()
.public void setRollbackOnly()
.public void setTransactionTimeout(int)
应用程序调用begin()来起动事务,即可调用commit()也可以调用rollback()来结束事
务。
使用JTA和JDBC
开发人员经常使用JDBC来作为DAO类中的底层数据操作。如果计划使用JTA来划分
事务,你将需要一个实现了javax.sql.XADataSource,javax.sql.XAConnection和
javax.sql.XAResource接口JDBC的驱动。实现了这些接口的驱动将有能力参与到JTA
事务中。一个XADataSource对象是一个XAConnection对象的工厂。XAConnections
是参与到JTA事务中的连接。
你需要使用应用程序服务器管理工具来建立XADataSource对象。对于特殊的指令请
参考应用程序服务器文档和JDBC驱动文档。
J2EE应用程序使用JNDI来查找数据源。一旦应用程序有了一个数据源对象的引用,
这会调用javax.sql.DataSource.getConnection()来获得数据库的连接。
XA连接区别于非XA连接。要记住的是XA连接是一个JTA事务中的参与者。这就意味
着XA连接不支持JDBC的自动提交特性。也就是说应用程序不必在XA连接上调用
java.sql.Connection.commit()或java.sql.Connection.rollback()。相反,应用程序应该
使用UserTransaction.begin()、UserTransaction.commit()和
UserTransaction.rollback().
选择最好的方法
我们已经讨论了JDBC和JTA是怎样划分事务的。每一种方法都有它的优点,回此你需
要决定为你的应用程序选择一个最适应的方法。
在我们团队许多最近的对于事务划分的项目中使用JDBC API来创建DAO类。这DAO
类总结如下:
.事务划分代码被嵌入到DAO类内部
.DAO类使用JDBC API来进行事务划分
.调用者没有划分事务的方法
.事务范围被限定在一个单一的JDBC连接
JDBC事务对复杂的企业应用程序不总是有效的。如果你的事务将跨越多个DAO对象
或
多个数据库,那么下面的实现策略可能会更恰当。:
.用JTA对事务进行划分
.事务划分代码被DAO分开
.调用者承担划分事务的责任
.DAO参与一个全局的事务中
JDBC方法由于它的简易性而具有吸引力,JTA方法提供了更多灵活性。你选择什么样
的实现将依赖于你的应用程序的特定需求。
日志记录和DAO
一个好的DAO实现类将使用日志记录来捕获有关它在运行时的行为细节。你可以选择
记录异常、配置信息、连接状态、JDBC驱动程序的元数据或查询参数。日志对开发