权衡 Apache Geronimo EJB 事务选项,第 1 部分: 容器管理事务
权衡 Apache Geronimo EJB 事务选项,第 1 部分: 容器管理事务
了解 Geronimo 和 OpenEJB 能为您做什么
Jonathan Sagorin (jonathan@javaoncall.com), 自由软件开发人员
Jonathan Sagorin 是一位自由开发人员。在 10 年职业生涯里,他大部分时间都是一名顾问,为用户提供自定义 Java 解决方案。业余时间他尝试玩垒球和即兴表演(不必同时进行,虽然他的垒球队友不这么认为)。
简介: 本系列分为三部分,将探索 Apache Geronimo 中的 Enterprise Java?Beans (EJB) 容器管理事务和 bean 管理事务。在第 1 部分中,将找出两种事务之间的差异,其中包括了解容器管理事务如何帮助您避免事务逻辑和管理的复杂性,从而使您可以专注于企业 bean 的业务逻辑。您还将学会如何在 Geronimo 应用服务器中实现容器管理事务,以及如何使用 Geronimo、OpenEJB 和 XDoclet 将自己从繁重的 EJB 编码工作中解放出来。
查看本系列更多内容
标记本文!
发布日期: 2006 年 10 月 23 日
级别: 初级
访问情况 434 次浏览
建议: 0 (添加评论)
1 star2 stars3 stars4 stars5 stars 平均分 (共 3 个评分 )
简介
OpenEJB 是为 Apache Geronimo 选定的 EJB 容器实例。虽然 EJB 3.0 目前已经面市,但直到发布 Geronimo 2.0 版,在 Geronimo 接受 Java 1.5 认证时,Geronimo 才支持 EJB。
本系列分为三部分,将使您了解 Geronimo 和 OpenEJB 可以为您提供什么帮助,以及在 EJB 2.1 中现在可以实现的 EJB 事务概念(让您顺利进入 EJB 3.0)。
EJB 框架提供的好处是:可以使用事务,但没有事务 API 编程的痛苦。在实现 EJB 事务时,您有两种选择:
* 告诉 EJB 容器处理所有的硬性事务工作(容器管理的事务)。
* 让企业 bean 处理一部分事务工作(bean 管理的事务)。
在本系列的第 1 部分中,将从事务的概述开始,然后讨论 EJB 2.1 中描述的 EJB 容器管理的事务。最后用一些代码片断结束介绍,这些代码将显示如何在 Geronimo 应用服务器上实现容器管理的事务。
在第 2 部分中,将获得 EJB 2.1 中 bean 管理的事务的概述,并查看一些示例代码实现。
在第 3 部分中,将综合这两种事务,并了解与容器管理的事务和 bean 管理的事务有关的难题和附加特性。
事务—— 概述
什么是事务?为什么它们如此重要?可以考虑一下银行事务这个非常简单的案例:将 100 美元从您的一个活期存款帐户转移到您的储蓄存款帐户。通过进一步的调查,可将这一操作分解为两个更小的操作:
* 银行从您的活期存款帐户减去 100 美元。
* 银行在您的储蓄存款帐户增加 100 美元。
如果银行将活期存款额减少 100 美元,但您的储蓄存款额并没有增加 100 美元,那么您可能会感到有点沮丧。就个人而言,我愿意将两个操作视为一个操作。因此,如果您的储蓄存款帐户从没有增加 100 美元,那么 100 美元也决不应从您的活期存款帐户中减去!
类似地,在应用过程中,很多业务案例都是进行整体确认的 (all-or-nothing approach)。一些大的操作由一个或多个更小的步骤组成。为了完成操作,操作中的所有 步骤都必须完成或不完成,这种行为称为原子 行为。
原子性是事务必须保证的四个特征(或属性)之一。其他三个属性是:
* 一致性
* 隔离性
* 耐久性
这四种属性一起被称为 ACID 属性。
ACID 属性
事务对这些已知 ACID 属性的描述为:
* 事务是原子的。所有操作都被认为是一个工作单元。像前面讨论的那样,是整体确认的。
* 事务是一致的。在执行事务之后,必须将系统维持在一致(或合法)状态下。合法状态的定义取决于系统。根据早先的示例,在执行任何撤消操作之后,银行指示您,将保留您的活期存款帐户为顺差。
* 事务是隔离的。每个事务在同一资源进行操作时与其他事务都是相互隔离的。这可通过数据的锁同步来实现。
* 事务是持久的。资源更新必须避免系统故障,如硬件或网络故障。在分布式系统中,当出现网络故障或数据库崩溃时,恢复过程是必需的。
事务模型
有两种流行的事务模型:flat 事务和 nested 事务。EJB 支持 flat 事务模型。
flat 事务是作为单个工作单元处理的一系列操作。工作单元只有两种结果:要么成功,要么失败。如果事务中的所有步骤都成功完成,则事务获得提交,并且该操作执行的所有持久存储数据更改都将永久化。如果事务中某一步骤失败,则事务将回滚 (roll back),并反转事务中步骤受影响的所有数据。
nested 事务允许事务嵌套在其他事务中。嵌套在其他事务中的事务允许在不影响其父事务的情况下进行回滚。失败的 nested 事务可以继续重试。如果再次失败,则可回滚父事务。
回页首
EJB 事务
EJB 是用于组件开发的一个框架。您开发的 EJB 将运行在 EJB 容器中。此外,EJB 容器为事务带来了一些好处。OpenEJB 是 Geronimo 用来提供事务管理的 EJB 容器。
EJB 架构支持分布式事务。一些需要分布式事务的场景模式范例包括:
* 更新多个数据库的单个事务中的应用。
* 从 Java Message Service (JMS) 目标发送或接收消息并更新一个或多个数据库的单个事务中的应用。
* 通过多个 EJB 服务器来更新多个数据库的单个事务中的应用。
* 在更新多个 EJB 服务器上的多个数据库之前,Java 客户端明确区分事务边界。
事务边界
在实现 EJB 事务时,您将划分事务边界:谁启动事务、谁提交或中止事务,以及什么时候使用事务。这取决于 EJB 容器和服务器提供商提供的事务管理和底层事务通信协议。
有两种划分方案:
* declarative 方案,使用该方案可以将事务实现委托给 EJB 容器。(该方案是本文其余部分的焦点。)
* programmatic 方案,在该方案中,企业 bean 使用自己的代码自己提供提交或中止信息。(本系列的第 2 部分中将介绍此方案。)
在使用 declarative 事务划分时,EJB 容器根据 EJB 部署描述符中由应用程序开发人员声明的指令,在企业 bean 的方法上应用事务边界。这称为容器管理的事务。
在实现 programmatic 划分事务时,应用程序开发人员负责将事务逻辑和界线编入企业 bean 代码中。这称为 bean 管理的事务。
我应该使用哪种事务?
容器管理的事务更加简单并且在代码中不需要实现事务逻辑,无论您的企业 bean 方法是否必须运行在事务中。此外,调用 bean 的 Java 客户端不能滥用您的企业 bean,因为事务始终是有始有终的。
如果想完全控制事务边界,请使用 bean 管理的事务。该方法允许在代码中直接控制提交或控制回滚逻辑发生的地方。
会话 bean 和消息驱动 bean (MDB) 可以使用 bean 管理的事务