2024年5月31日发(作者:)
5事务管理
为了描述事务的概念,我们拿买电影票来举例。买一张电影票通常有一下步骤:
检查剩余座位的数量,确定是否能给你提供你需要的座位个数
每卖出一张票,可用座位的数量就应该减一
付款
售票员把票给你
如果一切顺利的话,你就可以欣赏到一场一鸣惊人的电影,而影院也增加了收入。
但是如果有环节出差错了怎么办呢?比如说:你用来付款的信用卡没钱了?显然,
你不会拿到票,影院也拿不到钱。但是如果说座位的数量在下个人购买之前没有
被恢复到原来的状态,那么电影也许因为人为原因而不会满场了。或者如果出现
这样的情况:一切都很顺利,但是发放票的时候出了问题。你只好乖乖的呆在家
里看电视了,而且还损失了一小笔钱。
为了保证剧院和你都不受到损失,上面的操作应该用事务封装起来。作为事务,
它应该被看成是一个单独的动作,以保证要么所有的操作都成功,或者所有的操
作都回滚到初始的状态。
在软件中,事务有着举足轻重的地位,确保数据和资源保持一致的状态。如果没
有事务,那么数据有可能因为应用程序的业务逻辑而变成脏数据,或者变成与其
他数据不统一的数据。
让我们快速浏览一下事务向导和他是如何工作的。有以下四个因素。
5.1.1 用四句话来解释事务
在软件开发的一个重要传统里,可以用一个单词首字母的缩写来描述一个事务:
ACID,简言之,ACID代表
Atomic(原子性)事务由一个或多个动作绑定起来作为一个单独的工作单元。原
子性保证事务中所有的操作要么都执行,或者都不执行。如果所有的动作都执行
了,那么事务就是成功的,如果其中有一个动作失败了,那么整个事务都失败,
而且要执行回滚操作。
Consistent(一致性)一旦事务结束(可能成功了也可能失败了),那么系统所
模拟的业务逻辑要处于一致的状态。数据不应该被实体关系破坏。
Isolated(隔离性)事务应该允许多个用户操作一个数据,一个用户的操作应该
不受另一个用户操作的影响。因此事务之间应该是相互隔离的,以阻止他们在操
作中同时读写同一数据。(一般是以乐观锁来实现这一特性的)
Durable(持久性)一旦事务完成,事务执行的结果就应该被保存到数据库中,
这样即使因为某一原因系统崩了,数据还能保存下来。传统上是把结果保存到数
据库或者其他某种格式的持久化介质中。
在刚才的电影票的例子中,如果任何一个步骤失败的话事务可以所有取消操作的
结果来保证原子性。原子性可以通过保证系统的数据从来没有不一致的状态,和
从来没有部分执行的状况来保证一致性。隔离性可以通过阻止其他并发事务在你
正在购买你的座位的时候把这个座位从你那里偷走来保证一致性。
最终的效果就是持久性,因为它们已经被保存到存储介质中去了。如果系统崩了
或有其他类似的事件发生的话你也不需要担心事务的结果会丢失。
如果需要更详细的解释,我们建议你看看Martin Fowler写的Patterns of
Enterprise Application Architecture。尤其是第五章,讨论了并发和事务。
5.1.2 理解spring对事务处理的支持
和ejb一样,spring也提供了对包括的两种事务的支持,但是spring的事务管
理能力超过了ejb的事务管理能力。
Spring对代码级事务管理的支持很大程度上不同于ejb。与ejb不同的是,ejb
和jta实现是联系在一起的,spring使用的是一种招回机制以从从事务代码种抽
象出真实的事务实现。事实上,spring的事务管理甚至不需要一个jta的实现。
如果你的应用程序只使用一个单一的持久资源,那么你就可以使用持久机制提供
的事务支持来处理你的事务。这包括jdbc,hibernate,jdo和ojb。然而,如
果你的程序有涉及到多个资源的事务需求,spring可以用第三方的jta实现来提
供一个分布式的事务支持。在5.2种我们将讨论spring对代码级事务管理的支
持。
在你的代码中,代码级事务管理提供给你精确的弹性来定义的事务边界,声明式
事务在其事务规则中帮助你减弱了操作带来的影响。Spring对声明式事务处理
的支持让我们想起了ejb的容器管理事务(cmt)。两者都允许你们显式的定义
事务的边界。但是spring的声明式事务超出了cmt,因为它允许你声明附加的
属性,比如说隔离级别和timeouts。在5.3中我们将阐述spring的声明式事务
管理。
选择代码级事务管理还是声明式事务管理就决定了你是选择了对程序
(fine-grained)严密的控制还是选择了方便。当你把事务编写到你的代码中时,
你就可以精确的控制事务的边界,在你需要的地方精确的开始和结束事务。一般
的做法是,你不需要代码级提供的对程序的精密的控制时就选择把你的事务声明
到一个上下文环境中去(就是说选择声明式事务管理)。
不管你是否选择把事务写到你的bean中还是当作一个切面来声明它们,你将使
用一个spring的事务管理来作为接口插入到平台具体的事务实现中。让我们看
一下spring的事务管理是如何用平台的具体的事务实现把你从事务处理中解放
出来的。
5.1.3 介绍spring的事务管理


发布评论