Bean管理事务

Bean管理事务

在一个Bean管理事务中,会话Bean或者Message-driven Bean是用代码显式设置事务界线的。实体Bean不能使用Bean管理事务,只能使用容器管理的事务。虽然容器管理事务Bean需要较少的代码,但它也有一个局限:方法执行时,它只能关联一个事务或不关联任何事务。如果这个局限使你Bean编码困难,你应该考虑使用Bean管理事务。(译者:实际上J2EE服务器不支持嵌套事物,那么Bean管理事务唯一的优点就是可以在一个方法中一次启动多个事务)

??下面的伪码很好说明了Bean管理事对商业逻辑的紧密控制。通过检查各种条件,伪码决定是否在商业方法中启动或停止不同的事务。

begin transaction

...

update table-a

...

if (condition-x)

commit transaction

else if (condition-y)

update table-b

commit transaction

else

rollback transaction

begin transaction

update table-c

commit transaction

??当为会话Bean或Message-driver Bean的Bean管理事务编码时,你必须决定是使用jdbc或者JTA事务。下面的内容论述了两种事务类型。

JDBC 事务

??JDBC事务通过DBMS事务管理器来控制。你可能会为了使用会话Bean中的原有代码而采用JDBC事务将这些代码封装到一个事务中。使用JDBC事务,要调用java.sql.Connection接口的commit和rollback方法。事务启动是隐式的。一个事务的从最近的提交、回滚或连接操作后的第一个SQL的语句开始。(这个规则通常是正确的,但可能DBMS厂商的不同而不同)

代码资源

??下面的例子在j2eetutorial/examples/src/ejb/warehouse目录下。在命令行窗口中进入j2eetutorial/examples目录执行ant bank命令编译这些源文件,执行ant create-warehouse-table命令创建要用到的表,一个样本WarehouseApp.ear文件在j2eetutorial/example/ears 目录下。

??下面的代码来自WarehouseEJB例子,一个会话Bean通过使用Connection接口的方法来划定Bean管理事务界限。ship方法以调用名为con的连接对象的setAutoCommit方法开始,该方法通知DBMS不要自动提交每个SQL语句。接下来ship 方法更新order_item和inventory数据表。如果更新成功,这个事务就会被提交。如果出现异常,事务就回滚。

public void ship (String productId, String orderId, int

quantity) {

try {

con.setAutoCommit(false);

updateOrderItem(productId, orderId);

updateInventory(productId, quantity);

con.commit();

} catch (Exception ex) {

try {

con.rollback();

throw new EJBException("Transaction failed: " +

ex.getMessage());

} catch (SQLException sqx) {

throw new EJBException("Rollback failed: " +

sqx.getMessage());

}

}

}

JTA 事务

??JTA是Java Transaction API 的缩写。这些API 允许你用独立于具体的事务管理器实现的方法确定事务界限。J2EE SDK 事务管理器通过Java事务服务(Java Transaction Service, JTS)实现。但是你的代码并不直接调用JTS中的方法,而是调用JTA方法来替代,JTA方法会调用底层的JTS实现。

??JTA事务被J2EE 事务管理器管理。你可能需要使用一个JTA事务,因为它能够统一操作不同厂商的数据库。一个特定DBMS的事务管理器不能工作在不同种类的数据库上。然而J2EE事务管理器仍然有一个限制??它不支持嵌套事务。就是说,它不能在前一个事务结束前启动另一个事务。

??下面例子的源代码在j2eetutorial/examples/src/ejb/teller目录下,在命令行窗口进入j2eetutorial/examples目录,执行ant teller命令编译这些源文件,执行ant create-bank-teller命令创建要用到的表。一个样本TellerApp.ear文件在j2eetutorial/examples/ears目录下。

??要自己确定事务界限,可以调用javax.transaction.UserTransaction接口的begin、commit和rollback方法来确定事务界限(该接口只能在SessionBean中使用,实体Bean不允许使用用户自定义的)。下面选自TellerBean类的代码示范了UserTransaction的用法。begin和commit方法确定了数据库操作的事务界限,如果操作失败则调用rollback回滚事务并抛出EJBException异常。

public void withdrawCash(double amount) {

UserTransaction ut = context.getUserTransaction();

try {

ut.begin();

updateChecking(amount);

machineBalance -= amount;

insertMachine(machineBalance);

ut.commit();

} catch (Exception ex) {

try {

ut.rollback();

} catch (SystemException syex) {

throw new EJBException

("Rollback failed: " + syex.getMessage());

}

throw new EJBException

("Transaction failed: " + ex.getMessage());

}

}

非提交返回事务

??使用Bean管理事务的无状态会话Bean在事务返回前必须提交或者返回事务,而有状态的会话Bean没有这个限制。

??对于使用JTA事务的有状态会话Bean,Bean实例和事务的关联越过大量用户调用被保持,甚至被调用的每个商业方法都打开和关闭数据库连接,该市无关联也不断开,直到事务完成(或回滚)。

??对于使用JDBC事务的有状态会话Bean,JDBC连接越过用户调用保持Bean和事务之间的关联。连接关闭,事务关联将被释放。

在Bean管理事务中不允许使用的方法

??在Bean管理的事务中不能调用EJBContext接口的getRollbackOnly和setRollbackOnly方法,这两个方法只能在容器管理事务中被调用。在Bean管理事务中,应调用UserTransaction接口的getStatus和rollback方法。
[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/91551/viewspace-1004362/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/91551/viewspace-1004362/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值