清单 1. 资金转移的样本 SQL 代码 SELECT accountBalance INTO aBalance FROM Accounts WHERE accountId=aId; IF (aBalance >= transferAmount) THEN UPDATE Accounts SET accountBalance = accountBalance - transferAmount WHERE accountId = aId; UPDATE Accounts SET accountBalance = accountBalance + transferAmount WHERE accountId = bId; INSERT INTO AccountJournal (accountId, amount) VALUES (aId, -transferAmount); INSERT INTO AccountJournal (accountId, amount) VALUES (bId, transferAmount); ELSE FAIL "Insufficient funds in account"; END IF
假如我们把这个操作作为五个单独的事务来执行会发生什么情况?这样不仅会使执行速度变慢(由于事务开销),还会失去一致性。例如,假如一个人从帐户 A 取了钱,作为执行第一次 SELECT(检查余额)和随后的记入借方 UPDATE 之间的一个单独事务的一部分,会发生什么情况?这样会违反我们认为这段代码会强制遵守的业务规则 ? 帐户余额应该是非负的。假如在第一次 UPDATE 和第二次 UPDATE 之间系统失败会发生什么情况?现在,当系统恢复时,钱已经离开了帐户 A 但还没有记入帐户 B 的贷方,并且也无记录说明原因。这样,哪个帐户的所有者都不会开心。
事务模式 Bean 类型 在事务 T 内被调用时的行为 在事务外被调用时的行为 Required 会话、实体、消息驱动 在 T 中征用 新建事务 RequiresNew 会话、实体 新建事务 新建事务 Supports 会话、消息驱动 在 T 中征用 不带事务运行 Mandatory 会话、实体 在 T 中征用 出错 NotSupported 会话、消息驱动 不带事务运行 不带事务运行 Never 会话、消息驱动 出错 不带事务运行
在只使用容器治理的事务的应用程序中,只有组件调用事务模式为 Required 或 RequiresNew 的 EJB 方法时才启动事务。假如容器创建一个事务作为调用事务性方法的结果,当该方法完成时将关闭该事务。假如方法正常返回,容器将提交事务(除非应用程序已经要求回滚事务)。假如方法通过抛出一个异常退出,容器将回滚事务并传播该异常。假如在现有事务 T 中调用了一个方法,并且事务模式指定应该不带事务运行该方法或者在新事务中运行该方法,那么事务 T 将被暂挂,一直到方法完成,然后先前的事务 T 被恢复。
对于大多数数据库,缺省的隔离级别为“读已提交的”,这是个很好的缺省选择,因为它阻止事务在事务中的任何给定的点看到应用程序数据的不一致视图。“读已提交的”是一个很不错的隔离级别,用于大多数典型的短事务,比如获取报表数据或获取要显示给用户的数据的时候(多半是作为 Web 请求的结果),也用于将新数据插入到数据库的情况。
Jim Grey 和 Andreas Reuter 合著的 Transaction Processing: Concepts and Techniques 是关于事务处理这个主题的权威著作。
Philip Bernstein 和 Eric Newcomer 合著的 Principles of Transaction Processing 是关于这个主题的很好的介绍;它包含了许多历史和概念。
Ed Roman、Tyler Jewell 和 Scott Ambler 合著的 Mastering Enterprise JavaBeans 是关于 J2EE 和 EJB 技术的很好的介绍。
通过 Transaction Management under J2EE 1.2(JavaWorld,2000 年 7 月)学习声明式事务划分的基础知识。
来自 WebSphere 开发者园地的这篇技术记要量化减少隔离级别的好处。
白皮书“WebSphere application Server Development Best Practices for Performance and Scalability”描述了用来治理 J2EE 应用程序性能和可伸缩性的几种很有用的技术。
Visual Age 开发者园地上发表了一篇文章,这篇文章检查了 J2EE 应用程序中的数据库访问和并发治理问题。
PreciseJava 中的教程“Best practices to improve performance in JDBC”描述了几种有用的数据库应用程序性能最优化。
请在 developerWorks Java 技术专区中查找其它关于 Java 技术的内容。
关于作者 Brian Goetz 是一位软件顾问,在过去 15 年间一直从事专业软件开发。他是 Quiotix,一家位于加利福尼亚,洛斯拉图斯(Los Altos)的软件开发和咨询公司的总顾问。请参阅流行的业界出版物中 Brian 已经发表和即将发表的文章。您可以通过 brian@quiotix.com 与 Brian 联系。