SQL Server 2008编程入门经典笔记(第十四章:事务和锁)

时间:2022-02-05 04:17:56

第14章 事务和锁
14.1 事务
事务全部是关于原子性(atomicity)的。原子性的概念是指可以把一些事情当作一个单元来看待。从数据库的角度看,它是指应全部执行或全部都不执行的一条或多条语句的最小组合。
事务的默认长度为一条语句。

标记事务的开始和结束,以及事务的成功或失败。可以使用一些T-SQL语句在事务中“标记”这些点。
a)BEGIN TRAN:设置起始点。
b)COMMIT TRAN:使事务成为数据库中永久的、不可逆转的一部分。
c)ROLLBACK TRAN:本质上说想要忘记它曾经发生过。
d)SAVE TRAN:创建一个特定标记符,只允许作部分回滚。

14.1.1 BEGIN TRAN
事务的开始可能是事务过程中最容易理解的概念。它唯一的目的就是表示一个单元的开始。如果由于某种原因,不能或者不想提交事务,那么这就是所有数据库活动将要回滚的起点。也就是说,就数据库而言,它会忽略这个起点之后的最终没有提交的所有语句。
BEGIN TRAN[SACTION] [<transaction name> |<@transaction variable>]
 [WITH MARK [<description>]]

14.1.2 COMMIT TRAN
事务的提交是一个事务的终点。当发出COMMIT TRAN命令时,可以认为该事务是持久的。也就是说,事务的影响现在是持久的并会持续,即使发生系统故障也不受影响(只要有备份或者数据库文件没有被物理破坏就行)。撤销已完成事务的唯一方式是发出一个新的事务。从功能上而言,该事务是对第一个事务的反转。
COMMIT TRAN[SACTION] [<transaction name> |<@transaction variable>]

14.1.3 ROLLBACK TRAN
从关联的BEGIN语句开始发生的任何事情事实上都会被忘记。
ROLLBACK TRAN[SACTION] [<transaction name> |<save point name>|<@transaction variable>|<@savepoint variable>]

14.1.4 SAVE TRAN
保存事务从本质上说就是创建书签(bookmark)。为书签建立一个名称(可以有多个名称).在建立了“书签”之后,可以在回滚中引用它。创建书签的好处是可以回滚到代码中的特定点上-只要为想要回滚到的那个保存点命名。
SAVE TRAN[SACTION] [<save point name> |<@savepoint variable>]

14.2 SQL Server日志的工作方式
除了需要将所有的内容写入磁盘这种很少的情况外,数据库中数据的构成不仅包括物理数据库文件中的数据,而且还包括从最后一次的检查点后提交给日志的事务。

14.2.1 失败和回复
恢复(recovery)总是在SQL Server每次启动时发生。SQL Server获取数据库文件,并且应用自最后的检查点以后日志中任何提交的改变(通过把它们写入到物理数据库文件)。日志中任何没有相应提交的改变都会回滚。

14.3锁和并发
并发是指两个或两个以上的用户都尝试在同一时间与同一个对象交互。对每个用户来说,交互操作的本质都是不同的(更新、删除、读取、插入),处理控制对手竞争的理想方法根据其中用户的操作以及他们操作的重要性而改变。可同时成功运行的用户越多,并发程度就越高。处理并发问题对于系统性来说是关键性的,在数据库中处理并发的基础就是锁定处理。

1.脏读
如果一个事务读取的记录是另外一个未完成事务的一部分,那么这个时候就发生了脏读。
2.非重复性读取
如果在一个事务中两次读取记录,而另一个事务在这期间改变了数据,就会发生非重复性读取。
3.幻读
它是指在运行UPDATE语句的同时有人执行了INSERT语句。因为这是一个全新的数据行,所以没有被锁定,而且运行良好。解决这个问题的唯一方法是设定事务隔离级别为SERIALIZABLE,这种情况下,任何对表的更新都不能放入WHERE子句中,否则它们将被锁在外面。
4.丢失更新
丢失更新发生在一个更新成功写入数据库后,而又意外地被另一个事务重写时。如果有两个事务读取整个记录,然后其中一个向记录写入了更新信息,而另一个事务也向改记录写入更新信息,这是就会出现丢失更新。

14.3.4 锁定模式
1.共享锁
共享锁用于只需要读取数据的时候,也就是说不会改变任何内容。共享锁能和其他共享锁兼容。共享锁能做的是防止用户执行脏读。
2.排他锁
排他锁不与其他任何锁兼容,如果有任何其他的锁存在,则不能使用排他锁,而且当排他锁仍然起作用的时候,他们不允许在资源上创建任何形式的新锁。这可以防止两个人同时更新、删除或执行任何操作。
3.更新锁
更新锁是共享锁和排他锁的混合。更新锁表明了有一个共享锁,它在您完成初始数据扫描并指出需要更新的数据后变成排他锁。这说明了一个事实:更新操作有以下两个不同的阶段。
a)第一个阶段指出了满足WHERE子句条件的内容(需要更新的行)。这是更新查询的一部分,该查询有一个更新锁(共享锁起作用)。
b)第二个阶段是如果决定执行更新,那么锁将升级为排他锁。否则,将把锁转换为共享锁。
更新锁是防止了死锁。
4 意向锁
它用来处理对象层次问题的。假如一下如下情况:已对某一行建立了锁,但是有人想在页或者区段上建立锁,或者修改表。您肯定不想让另一个事务通过达到更高的层次来妨碍您。
如果没有意向锁,那么较高层次的对象将不会知道在较低层次上有锁。意向锁可改进性能,因为SQL Server只需要在表层次上检查意向锁(而不需要检查表上的每个行锁或者页锁),以此来决定事务是否可以安全地锁定整个表。

事务和锁都是SQL Server工作原理的基石,他们能使SQL Server中解决方案的开发最佳化。
原子性:事务要么全部执行,要么全部不执行。
一致性:需要遵守所有的约束以及其他的数据完整性规则,并且完全地更新所有相关的对象。
隔离性:每个事务都与任何其他事务完全地隔离。一个事务的动作不会受到另一个事务的干扰。
持久性:完成事务后,它的作用结果将永远存在于系统内。数据是“安全的”,这是指在诸如停电或其他非磁盘系统故障的情况下也不会导致发生数据只写入一半的情况。