
第9单元 事务和锁
学习目标
î掌握事务到概念、特征、操作原则
î掌握锁到概念、作用、分类及死锁处理
一 、事务的基本概念
在SQL Server 中,事务是一个很重要的概念。事务在SQL Server中相当于
一个工作单元,使用事务可以确保同时发生的行为和数据的有效性不发生
冲突,并且维护数据的完整性,确保SQL数据的有效性。
事务是SQL Server中的单个逻辑工作单元,一个事务内的所有语句被作为
一个整体执行。在事务执行过程中,如果遇到错误,则可以回滚事务,取消
该事务所做的全部改变或部分改变,从而保证数据库的一致性和可恢复性。
也就是说,一个事务要么其中的语句全部正确执行,要么全部语句不起作用。
1.并发控制
在多用户系统中,允许多个用户和事务同时访问同一个数据库中相同的数据。
为了避免同时发生的事务彼此间的相互干涉,需要进行并发处理控制。
并发性是用来解决多个用户对同一数据进行操作时的问题。特别是对于网络
数据库来说,这个特点更加突出。假设有一个订票系统里还有50张票,
在9:00这个时刻,甲乙同时在2个窗口买票,甲买5张,乙买10张。
正常情况下剩余票数是50-5-10= 35张。如果数据库没有并发手段,
则会出现以下两种情况:(1)甲先买上,将剩余票45写入数据库;
乙后买上,将40写回数据库,因此剩余票数为40。
(2)乙先买上,将剩余票40写入数据库;甲后买上,将45写回数据库,
因此剩余票数为45。很显然,正是由于数据库用户对数据的并发访问
导致发生了不可预见的结果,这种现象的发生破坏了数据的一致性和完整性。
并发操作带来的数据不一致性包括四类:
丢失修改、脏读、不可重复读取和幻读。
(1)丢失修改当两个或多个事务选择同一数据,然后基于最初选定的值更新
该数据时,会发生丢失更新问题。由于每个事务都不知道其他事务的存在,
最后的更新会重写由其他事务所做的更新,这将导致数据丢失。
例如,两个编辑人员制作了同一文档的电子副本。
每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了
原始文档。最后保存其更改副本的编辑人员覆盖另一个编辑人员所做的更改。
如果我们规定:在第一个编辑人员完成并提交事务之前,另一个编辑人员
不能访问同一文件,则可避免此问题。
(2)脏读当第二个事务选择其他事务正在更新的行时,会发生未提交的依赖
关系问题。第二个事务正在读取的数据还没有提交并且可能由更新此行的事务
所更改。例如,一个编辑人员正在更改电子文档。在更改过程中,另一个编辑
人员复制了该文档(该副本包含到目前为止所做的全部更改)并将其分发给预期
的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所
做的编辑并保存了文档。分发给用户的文档包含不再存在的编辑内容,并且这些
编辑内容应视为从未存在过。如果我们规定:在第一个编辑人员保存最终更改
并提交事务之前,任何人都不能读取更改的文档,则可以避免此问题。
(3)不可重复读取当第二个事务多次访问同一行且每次读取不同的数据时,
会发生不一致的分析问题。不一致的分析与未提交的依赖关系类似,因为其他
事务也是正在更改第二个事务正在读取的数据。但是,在不一致的分析中,
第二个事务读取的数据是由已进行了更改的事务提交的。此外,不一致的分析
涉及多次(两次或更多)读取同一行,而且每次信息都被其他事务更改,
因此我们称为“不可重复读”。
例如,编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。
当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果我们
规定:在编辑人员完成最后一次读取文档之前,作者不能更改文档,则可以
避免此问题。
(4)幻读当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的
范围时,会发生幻读问题。由于其他事务的删除操作,事务第一次读取的行
的范围显示有一行不再存在于第二次或后续读取内容中。同样,由于其他事务
的插入操作,事务第二次或后续读取的内容显示有一行并不存在于原始读取
内容中。
2.数据库恢复
数据库恢复是指数据库系统在进行的某事务失败后重新恢复之前的数据操作,
体现了事务的原子性。例如,当一个顾客在超市购买商品,在出口结账时,
商品信息是逐条被终端扫描并记录的,但是,整个购买行为会被作为一个
事务在所有商品信息扫描完毕后提交给数据库系统的。然后,系统再执行
该事务,修改数据库中有关收入和存货清单的数据表。如果数据库突然发生
故障,顾客的购买行为没有全部完成,如果不对数据库进行恢复操作,会使
数据库系统恢复后的数据维护以及当前的客户结账造成麻烦。因为已经把该
客户的整个购买行为定义为事务,所以这时就只需要撤销其事务即可。为了
保证事务的原子性,在执行一个数据库更新操作时,可以先把描述更新操作
的信息写入存储器,而不修改数据库本身。当事务提交时,再使用存储器中
存储的更新操作信息来实现数据库的更新。破坏事务原子性和引起系统故障的
原因主要如下。计算机系统故障:在事务运行过程中发生的硬件或软件故障。
事务或系统错误:事务中的某些操作或者是错误的参数引起的事务的失败。
事务的强行终止:事务经常具有测试某些特殊情况发生的功能。当测试的情
况发生时,事务被强行终止。
二、 事务的特性
每一个商业过程都包括一个或多个事务。想象一下,我们正在管理一个网上书店。一个消费者定购一个产品后,必须执行一个预先定义的进程才能确保交货及时。这个进程还必须包括信用卡的处理过程以保证公司收到了货款。如果这些任务中有一个失败了并且不能更正,那么整个过程必须取消,以保证消费者在得到商品前不能给他开发票。
与一个商业事务相关的数据必须改为可靠、一致、完整的数据以符合实际的商业过程,这可以通过在数据库级使用事务来完成。事务用于确保数据库的一致性,如果用户正在对数据库进行写操作,那么借助事务的正确使用,用户可以保证要么该过程彻底成功,要么数据库被恢复到它在写操作开始之前所处于的那个状态。这就是事务在数据库中的主要用途—一它们把数据库从一个一致状态带到下一个一致状态。当我们在数据库中提交工作,事务保证我们的修改要么全部得到保存,要么全部得不到保存。
为了能做到这一点,事务必须满足原子性、一致性、隔离性和持续性四个原则。
(1)原子性(Atomicity)。一个事务中的所有语句被作为单个执行单元来对待。整个单元必须完整地结束,或者该事务被认为已经失败且必须被回退。
(2) 一致性(Consistency)。一致性意味着数据库的状态在一个事务之前和之后都是有效的。如客户购买一件商品,数据库应显示商店收到来自客户的付款,并且库存减少一件商品。
如果该事务被提交,但那两个修改的某一个没有发生,那么数据库将不是处于一个有效状态,要么库存将是错误的,要么商店的收支状况将是错误的。
(3)隔离性(lsolation):即不同的事务之间不能相互干扰。这种要求有时也被称为事务的串行性。
(4)持续性(Durability)。指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。即使在该提交后的那一时刻有一个彻底的系统故障,但在系统重新启动后,数据库仍显示该事务的执行结果。
(一)事务的分类
1.自动事务模式
在自动事务模式下,每条单独的语句都是一个事务。当一个语句被成功执行后自动提交,当它执行过程中产生错误时自动回滚。
2.显式事务
显式事务是指显式定义了其启动和结束的事务。显式事务以BEGIN TRANSACTION语句显式开始,以COMMIT或ROLLBACK语句显式结束。
3.隐式事务
执行“SET IMPLICIT_TRANSACTIONS ON”语句可以使SQL Server 进入隐式事务模式。 当连接以隐性事务模式进行操作时,SQL Server实例将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或回滚每个事务。隐性事务模式生成连续的事务链。在使用隐式事务时要小心,不要忘记提交或回退工作。