事务主要是一种异常处理机制

 事务主要是一种异常处理机制。事务在程序中的用途与合法合同在日常业务中的用途相似:如果出了什么问题它们可以帮助恢复。但由于大多数时间内都没实际 发生什么错误,我们就希望能够尽量减少它们的开销以及对其余时间的占用。我们在应用程序中如何使用事务会对应用程序的性能和可伸缩性产生很大的影响。

  事务划分

  J2EE 容器提供了两种机制用来定义事务的起点和终点:bean 管理的事务和容器管理的事务。在 bean 管理的事务中,用 UserTransaction.begin() 和 UserTransaction.commit() 在 bean 方法中显式开始和结束一个事务。另一方面,容器管理的事务提供了更多的灵活性。通过在装配描述符中为每个 EJB 方法定义事务性属性,您可以指定每个方法的事务性需求并让容器确定何时开始和结束一个事务。无论在哪种情况下,构建事务的基本指导方针都是一样的。

  进来,出去

  事务划分的第一条规则是“尽量短小”。事务提供并发控制;这通常意味着资源管理器将代表您获得您在事务期间访问的数据项的锁,并且它必须一直持有这些锁,直到事务结束。(请回忆一下本系列第 1 部分所讨论的 ACID特性,其中“ACID”的“I”代表“隔离”(Isolation)。也就是说,一个事务的结果影响不到与该事务并发执行的其它事务。)当您拥有锁时,任何需要访问您锁定的数据项的其它事务将不得不一直等待,直到您释放锁。如果您的事务很长,那些其它的所有事务都将被锁定,您的应用程序吞吐量将大幅度下降。

wpgjyl32.com
lgylc483.com
zsylc659.com
lqzylc754.com
ktvylc15.com

  规则 1:使事务尽可能短小。

  通过使事务尽量短小,您可以把阻碍其它事务的时间缩到最短,从而提高应用程序的可伸缩性。保持事务尽可能短小的最好方法当然是不在事务中间做任何不必要耗费时间的事,特别是不要在事务中间等待用户输入。

  开始一个事务,从数据库检索一些数据,显示数据,然后在仍处于事务中时请用户做出一个选择可能比较诱人。千万别这么做!即使用户注意力集中,也要花费数秒来响应 ― 而在数据库中拥有锁数秒的时间已经是很长的了。如果用户决定离开计算机,或许是去吃午餐或者甚至回家一天,会发生什么情况?应用程序将只好无奈停机。在事务期间执行 I/O 是导致灾难的秘诀。

  规则 2:在事务期间不要等待用户输入。

  将相关的操作归在一起

  由于每个事务都有不小的开销,您可能认为最好是在单个事务中执行尽可能多的操作以使每个操作的开销达到最小。但规则 1 告诉我们长事务对可伸缩性不利。那么如何实现最小化每个操作的开销和可伸缩性之间的平衡呢?

  我们把规则 1 设置为逻辑上的极端 ― 每个事务一个操作 ― 这样不仅会导致额外开销,还会危及应用程序状态的一致性。假定事务性资源管理器维护应用程序状态的一致性(请回忆一下第 1 部分,其中“ACID”的“C”代表“一致性”(Consistency)),但它们依赖应用程序来定义一致性的意思。实际上,我们在描述事务时使用的一致性的定义有点圆滑:应用程序说一致性是什么意思它就是什么意思。应用程序把几组应用程序状态的变化组织到几个事务中,结果应用程序的状态就成了 定义上的(by definition)一致。然后资源管理器确保如果它必须从故障恢复的话,就把应用程序状态恢复到最近的一致状态。

posted on 2014-03-11 10:38  有木有格子  阅读(227)  评论(0编辑  收藏  举报