介 绍:
J2EE为应用开发提供了大量的功能,但是为Servlets开发提供的却很少。Servlets开发者可能很难使用J2EE提供的这些功能,既不愿意也没有足够的时间将简单的Servlets容器替换为一个大型的、提供了多余功能的J2EE服务器。无论如何,利用J2EE的模块化特性,有可能通过将一些小型的、实现J2EE规范功能的应用组件集成到Servlet 容器中来增强Web应用,其中一项功能就是事务。
对于J2EE事务的完整描述可以参考其他文章,目前,只需要知道事务就是具有四个特性的、对资源(例如:数据库)的序列操作,事务的特性通常称为ACID:
原子化(Atomicity):事务的操作或者都成功(事务被提交),或者都失败(事务被回滚)。这是全有-全无属性。一个事务应该被看作是工作的一个单独单元。在事务中绝对没有混合了完成和未完成的操作。
一致性(Consistency):一个完成的事务将资源从一种有效状态变为另一种有效状态。对于一致性的具体例子就是数据库中的引用一致性和表中的主键。
隔离性(Isolation):在事务提交之前,事务中对于共享资源的改变在事务之外不具有可见性。独立性保证了事务不会访问并发修改的资源。
持续性(Durability):事务一旦成功完成,各项修改都能从失败中恢复过来。
JOTM(Java Open Transaction Manager)是一个由ObjectWeb组织开发的全功能的、开放源代码的单独事务管理器,它为Java应用提供了事务支持,并且完全兼容JTA(Java Transaction API)。你可以从JOTM的主页找到更多细节。将JTOM集成到Tomcat(或者其它的Servlet容器)使得JSP和Servlet开发者可以用一种轻量级的方法用事务的优势创建更强壮的Web应用。
为了说明事务可以怎样增强Web应用,让我们来考虑一个经典的、使用浏览器与客户交互的ATM实例。
ATM实例:
场景:
用例非常简单:一个用户想要从ATM取钱。他提供他的名字,john_doe,和他要取的现金的数额,50元。如果在他银行账户上有足够的钱,并且ATM有足够的现金,那么应用程序会提供给他现金并从他的银行账户上扣除相应的金额。否则,操作会取消,除了返回错误信息之外,任何事情都不会发生。为了集中于事务处理并让事情变得简单,我们不需要关心有关安全问题,假设用户已经通过安全认证了。
这个非常简单的例子如果要实现强壮性而没有事务支持就会变得出奇的困难。一个客户端应用包括了对两个不同资源的操作:ATM和用户的银行账户。在应用设计中自然就提出了ACIDity的问题,举例来说,如果ATM的操作成功而银行账户的操作失败(可能由于通信故障),用户将会取到现金而银行账户不会被更新,对银行来说是个糟糕的消息。
更不幸的是,如果银行账户更新正确而ATM提供现金时出现错误,那么用户取不到现金,但是他的银行账户会扣除相应的数额。
为了防止上述事情发生,在你的应用程序中,你可以:
1) 连接两个资源并通知它们用户目前正在进行的所有操作;
2) 询问它们是否可以进行这些操作,并且…;
3) 如果它们都认同,则要求它们执行操作。
如果另一个操作在第二、三部之间从用户的账户上提钱,那么即使以上的解决方案仍然不够强壮,也可能会发生现金提取错误,比如,如果用户的银行账户不允许出现负数的情况。
这里就是事务可以让你的应用更简单和强壮的地方了,通过将所有对两种资源的操作封装在同一个事务中,可以为你解决ACIDity的问题。