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@]
??下面的伪码很好说明了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方法。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/91551/viewspace-1004362/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/91551/viewspace-1004362/