EJB2.0的事务处理(待续)

1.EJB事务分类

  •     容器管理事务的回滚

        你能够在任何企业Bean中使用容器管理事务:会话Bean、实体Bean或者 Message-driven Bean。容器管理事务可以分两种:

       第一,如果产生一个系统异常,容器将自动回滚该事务。

       第二,通过调用EJBContext接口SetRollbackOnly方法,Bean方法通知容器回滚该事务。如果Bean抛出一个应用异常,事务将不会自动回滚,但可以调用SetRollbackOnly回滚。

 

 

  • bean管理事务

     在一个Bean管理事务中,会话Bean或者Message-driven Bean是用代码显式设置事务界线的。实体Bean不能使用Bean管理事务,只能使用容器管理的事务。虽然容器管理事务Bean需要较少的代码,但它也有一个局限:方法执行时,它只能关联一个事务或不关联任何事务。如果这个局限使你Bean编码困难,你应该考虑使用Bean管理事务

     其中bean管理事务可以分为JDBC事务

      JDBC 事务

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

     JTA 事务

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

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

    要自己确定事务界限,可以调用javax.transaction.UserTransaction接口的begin、commit和rollback方法来确定事务界限(该接口只能在SessionBean中使用,实体Bean不允许使用用户自定义的)。

 

 

2.事务属性

 

 

Required
如果客户端正在一个运行的事务中调用一个企业Bean的方法,这个方法就在这个客户端的事务中执行。如果客户端不关联一个事务,这个容器在运行该方法前开始一个新的事务。

Required属性在许多事务环境中可以很好的工作,因此你可以把它作为一个默认值,至少可以在早期开发中使用。因为事务的属性是在部署描述符中声明的,在以后的任何时候修改它们都很容易。

RequiresNew
如果客户端在一个运行的事务中调用企业Bean的方法,容器的步骤是:

1.挂起客户端的事务

2.开始一个新的事务

3.代理方法的调用

4.方法完成后重新开始客户端的事务

如果客户端不关联一个事务,容器运行这个方法以前同样开始一个新的事务。如果你想保证该方法在任何时候都在一个新事物中运行,使用RequiresNew属性。

Mandatory
如果客户端在一个运行的事务中调用企业Bean的方法,这个方法就在客户端的事务中执行。如果客户端不关联事务,容器就抛出TransactionRequiredException 异常。

如果企业Bean的方法必须使用客户端的事务,那么就使用Mandatory属性。

NotSupported
如果客户端在一个运行的事务中调用企业Bean的方法,这个容器在调用该方法以前挂起客户端事务。方法执行完后,容器重新开始客户端的事务。

如果客户端不关联事务,容器在方法运行以前不会开始一个新的事务。为不需要事务的方法使用NotSupported属性。因为事务包括整个过程,这个属性可以提高性能。

Supports

如果客户端在一个运行的事务中调用企业Bean的方法,这个方法在客户端的事务中执行,如果这个客户端不关联一个事务,容器运行该方法前也不会开始一个新的事务。因为该属性使方法的事务行为不确定,你应该谨慎使用Supports属性。

Never

如果客户端在一个运行的事务中调用企业Bean的方法,容器将抛出RemoteException异常。如果这个客户端不关联一个事务,容器运行该方法以前不会开始一个新的事务。


例子:

假设有两个EJB,EJB1和EJB2。EJB1的method1中n次调用EJB2的method2.典型代码如下:

method1{

  for(int i=0;i<n;i++){

    EJB2的method2..

}

}

如果在for循环到第j次异常.那么如果method1为Required,method2为Required,则会回滚所有的操作.结果就是

method2 对于i从0--j的所有数据库操作都回滚.method1也回滚.因为都是同一个事务

如果在for循环到第j次一场,那么如果method1为Required,method2为RequirsNew,则不会回滚所有的操作.结果就是method2对于i从0--j的所有数据库操作都不回滚.但method1回滚.因为对于不同的i值.都为新的事务。

如果想让程序执行i从0--n次.那么需要记录执行正常和不正常的情况.此时只要try,catch 其中EJB的method2就可.在catch代码中记录异常情况.这样因为没有再throw异常给method1。代码可以一直执行n次。达到记录正常和异常的记录。当然对method1不使用事务,method2使用required也可以达到目的.对method1不使用事务的简单方法就是 设置其为Bean管理EJB,并在代码中不手动开启事务

 

你可能感兴趣的:(java,bean,数据库,jdbc,api,ejb)