事务分为Required,RequiresNew,Mandatory,NotSupported和Never
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,并在代码中不手动开启事务