EJB3中Bean管理的事务分隔

本文详细阐述了EJB容器如何管理和协调使用Bean管理事务的企业Bean实例,包括不同场景下的事务处理逻辑,如会话Bean和消息驱动Bean的事务管理、事务的提交与回滚流程等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意,只有会话和消息驱动bean 可以用于bean 管理的事务分隔。

容器必须按下列方式管理客户对使用bean 管理事务分隔的企业bean 实例的调用。当客户通过企业bean 的客户端视图接口调用它的业务方法时,容器挂起所有可能与和客户请求相关的事务。如果实例关联有事务(如果有状态会话bean实例在前面的业务方法中启动了这个事务),容器就使用者事务和方法执行关联。

如果有拦截器方法和bean 实例关联,则会在拦截器方法调用之前进行关联。

容器必须可以让企业bean 的业务方法、消息监听器方法、拦截器方法或超时回调方法通过依赖注入和通过javax.ejb.EJBContext 接口查找,以及使用JNDI命名上下文java:/UserTransaction 获得javax.transaction.UserTransaction。当实例使用javax.transaction.UserTransaction 来分隔事务时,容器必须在begin 和commit或rollback 之间征用实例使用的所有资源管理器。当实例提交事务时,容器负责事务提交的全局协调(通常容器依赖事务管理器,它是EJB 服务器跨所有征用的资源管理器执行两阶段提交的一部分。如果事务只涉及一个资源管理器并且配置为可以使用连接共享,那么容器可以使用本地事务优化。)。

对于有状态bean,可以在没有提交或回滚事务的情况下完成启动事务的业务方法。在这种情况下,容器必须在多个客户端调用之间保留事务和实例的关联直到实例提交或回滚事务。当客户端调用下一个业务方法时,容器必须在事务上下文中调用这个业务方法(以及任何应用到这个bean 上的拦截器方法)。

如果有状态会话bean 实例在业务方法或拦截器方法内启动一个事务,那么它必须在业务方法(或所有的拦截器方法)返回之前提交事务。容器必须检测这种情况:一个事务在业务方法或拦截器方法中被启动但是没有完成。这种情况的处理如下:
记录为应用错误以警告系统管理员
回滚启动的事务
丢弃会话bean 实例
抛出javax.ejb.EJBException(如果业务接口是一个继承java.rmi.Remote的远程业务接口,那么抛出java.rmi.RemoteException)。如果使用EJB2.1客户端视图, 如果客户端是远程客户端则容器应当抛出java.rmi.RemoteException ; 如果客户端是本地客户端则抛出javax.ejb.EJBException。

如果消息驱动bean 实例在消息监听器方法或拦截器方法内启动事务,那么它必须在消息监听器方法(或所有的拦截器方法)返回之前提交事务。容器必须检测这种情况:事务在消息监听器方法或拦截器方法内被启动但没有完成,并且按照以下方式处理:
记录为应用错误以警告系统管理员。
回滚启动的事务
丢弃消息驱动bean 实例

如果会话bean 或消息驱动bean 实例在超时回调方法内启动事务,则它必须在超时回调方法返回之前提交事务。容器必须检测这种情况:事务在超时回调方法内被启动但没有完成,并按以下方式处理:
记录为应用错误以警告系统管理员。
回滚启动的事务
丢弃bean 的实例

对使用bean 管理的事务容器执行的动作总结在下表中。T1 是一个和客户端请求关联的事务,T2 是一个当前和实例关联的事务(也就是说,是一个由前一个业务方法启动但没有完成的事务)。对使用bean 管理事务的bean 方法容器的动作如下
客户端事务 当前和实例关联的事务 和方法关联的事务
None None None
T1 None None
None T2 T2
T1 T2 T2
对每一个条目描述如下:
如果客户端请求没有关联事务而且实例也没有关联事务,或者如果bean是消息驱动bean,容器调用未指定事务上下文的实例。
如果客户端请求关联了事务T1,但是实例没有关联事务,那么容器挂起客户端关联的事务并且调用未指定事务上下文的方法。当方法(包括它关联的拦截器方法)完成后再次唤醒客户端事务T1。对于消息驱动bean 或无状态bean 的web 服务终端方法调用来说,永远都不会发生这种情况。
如果客户端请求没有关联事务但实例已经关联了事务T2,那么容器容器调用管理事务T2 的实例。对于无状态会话bean 或消息驱动bean,永远都不会发生这种情况:只会发生在有状态会话bean 上。
如果客户端关联了事务T1,但实例关联事务T2,容器挂起客户端事务然后调用使用T2 事务上下文的实例方法。当方法(包括它的所有拦截器方法)完成后,容器重新使用客户端事务T1. 对于无状态会话bean或消息驱动bean,永远都不会发生这种情况:只会发生在有状态会话bean 上。

容器必须允许企业bean 实例在一个方法内按顺序执行几个事务。

在实例没有提交前一个事务时, 如果实例使用javax.transaction.UserTransaction 的方法begin 启动事务,那么容器必须在begin方法内抛出javax.transaction.NotSupportedException。

如果使用bean管理事务分隔的bean 实例调用javax.ejb.EJBContext的setRollbackOnly 或getRollbackOnly 方法,那么容器必须抛出java.lang.IllegalStateException。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值