事务和封锁

 
事务和封锁
1. 事务
1.1 事务相关:
1.1.1 事务 (transaction):
组合到工作的一个逻辑单元中的一组数据库操作,或者完全提交,或者回滚。事务是原子的、一致的、隔离的和持久的。
1.1.2 事务处理 (transaction processing):
用于有效记录某机构感兴趣的业务活动(称为事务)的数据处理。通常,联机事务处理 (OLTP) 系统执行大量的相对较小的事务。
1.1.3 事务回滚 (transaction rollback) :
将用户指定的事务回滚到事务内上一个保存点或事务的起始。
1.1.4 提交 (commit) :
保存自事务开始时起对数据库、多维数据集或维度进行的所有更改的操作。提交保证事务的所有修改在数据库、多维数据集或维度中都永久有效。提交还释放事务所使用的资源(如锁)。
1.1.5 回滚 (roll back) :
删除由一个或多个部分完成的事务执行的更新。为在应用程序、数据库或系统错误后还原数据库的完整性,需要使用回滚。
1.1.6 保存点 (savepoint):
使应用程序可以在遇到次要错误时回滚部分事务的标记。应用程序仍必须在事务完成时提交或回滚完整事务。
1.2 并发问题:
1.2.1 丢失更新:
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。
1.2.2 未确认的相关性(脏读Dirty Read):
当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。(读到的数据被回滚)
1.2.3 不一致的分析(非重复读、不可重复读Non-repeatable read):
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。
1.2.4 幻像读(幻像phantom):
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。
1.3 乐观和悲观并发:
乐观并发控制使用游标。SQL Server 默认使用悲观并发控制。
1.3.1 乐观并发
乐观并发控制假定不太可能(但不是不可能)在多个用户间发生资源冲突,允许不锁定任何资源而执行事务。只有试图更改数据时才检查资源以确定是否发生冲突。如果发生冲突,应用程序必须读取数据并再次尝试进行更改。
1.3.2 悲观并发
悲观并发控制根据需要在事务的持续时间内锁定资源。除非出现死锁,否则事务肯定会成功完成。
2. 封锁
2.1 SQL Server 中的锁定介绍
SQL Server具有多粒度锁定,允许一个事务锁定不同类型的资源。为了使锁定的成本减至最少,SQL Server 自动将资源锁定在适合任务的级别。锁定在较小的粒度(例如行)可以增加并发但需要较大的开销,因为如果锁定了许多行,则需要控制更多的锁。锁定在较大的粒度(例如表)就并发而言是相当昂贵的,因为锁定整个表限制了其它事务对表中任意部分进行访问,但要求的开销较低,因为需要维护的锁较少。
SQL Server 可以锁定以下资源(按粒度增加的顺序列出):
资源
描述
RID
行标识符。用于单独锁定表中的一行。
索引中的行锁。用于保护可串行事务中的键范围。
8 千字节 (KB) 的数据页或索引页。
扩展盘区
相邻的八个数据页或索引页构成的一组。
包括所有数据和索引在内的整个表。
DB
数据库。
 
SQL Server 使用不同的锁模式锁定资源,这些锁模式确定了并发事务访问资源的方式。
SQL Server 使用以下资源锁模式:
锁模式
描述
共享 (S)
用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。
更新 (U)
用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。
排它 (X)
用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时对同一资源进行多重更新。
意向
用于建立锁的层次结构。意向锁的类型为:意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。
架构
在执行依赖于表架构的操作时使用。架构锁的类型为:架构修改 (Sch-M) 和架构稳定性 (Sch-S)。
大容量更新(BU)
向表中大容量复制数据并指定了 TABLOCK 提示时使用。
 
2.1.1 共享锁
共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。
2.1.2 更新锁
更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。
若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。
2.1.3 排它锁
排它 (X) 锁可以防止并发事务对资源进行访问。其它事务不能读取或修改排它 (X) 锁锁定的数据。
2.1.4 意向锁(intent lock)
放置在资源层次结构的一个级别上的锁,以保护较低级别资源上的共享或排它锁。意向锁表示 SQL Server 需要在层次结构中的某些底层资源上获取共享 (S) 锁或排它 (X) 锁。例如,放置在表级的共享意向锁表示事务打算在表中的页或行上放置共享 (S) 锁。在表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排它 (X) 锁。意向锁可以提高性能,因为 SQL Server 仅在表级检查意向锁来确定事务是否可以安全地获取该表上的锁。而无须检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。
意向锁包括意向共享 (IS)、意向排它 (IX) 以及与意向排它共享 (SIX)。
锁模式
描述
意向共享
(IS)
通过在各资源上放置 S 锁,表明事务的意向是读取层次结构中的部分(而不是全部)底层资源。
意向排它
(IX)
通过在各资源上放置 X 锁,表明事务的意向是修改层次结构中的部分(而不是全部)底层资源。IX 是 IS 的超集。
与意向排它共享
(SIX)
通过在各资源上放置 IX 锁,表明事务的意向是读取层次结构中的全部底层资源并修改部分(而不是全部)底层资源。允许顶层资源上的并发 IS 锁。例如,表的 SIX 锁在表上放置一个 SIX 锁(允许并发 IS 锁),在当前所修改页上放置 IX 锁(在已修改行上放置 X 锁)。虽然每个资源在一段时间内只能有一个 SIX 锁,以防止其它事务对资源进行更新,但是其它事务可以通过获取表级的 IS 锁来读取层次结构中的底层资源。
 
2.1.5 架构锁
执行表的数据定义语言(DDL)操作(如添加列或除去表)时使用架构修改 (Sch-M) 锁。
当编译查询时,使用架构稳定性 (Sch-S) 锁。架构稳定性 (Sch-S) 锁不阻塞任何事务锁,包括排它 (X) 锁。因此在编译查询时,其它事务(包括在表上有排它 (X) 锁的事务)都能继续运行。但不能在表上执行 DDL 操作。
2.1.6 大容量更新锁
当将数据大容量复制到表,且指定了 TABLOCK 提示或者使用 sp_tableoption 设置了 table lock on bulk 表选项时,将使用大容量更新 (BU) 锁。大容量更新 (BU) 锁允许进程将数据并发地大容量复制到同一表,同时防止其它不进行大容量复制数据的进程访问该表。
 
3. 隔离级别 (isolation level)
3.1 隔离级别的概念:
控制隔离数据以供一个进程使用并防止其它进程干扰的程度的事务属性。设置隔离级别定义了 SQL Server 会话中所有 SELECT 语句的默认锁定行为。
3.2 事务隔离级别
按渐增保护的顺序,可用的隔离级别有:
l         混沌(Chaos)。可以看到由其它事务所做的未提交更改,但更新锁未保持到事务的结束。不支持回滚。SQL Server 不支持此隔离级别。
l         未提交读(Read Uncommitted)。可以看到其它事务所作的未提交更改。
l         提交读(Read Committed)。在提交其它事务之前,无法看到这些事务所做的更改。
l         可重复读(Repeatable Read)。在已经读取的值中保证看不到由其它事务所做的任何更改。
l         可串行读(Serializable)。保证所有并发事务之间的交互作用只与全部逐个执行每个事务时产生的效果相同。 当事务读出满足条件的记录集后对这个记录集加S锁。
隔离级别
丢失更新
脏读
不可重复读取
幻像
混沌
未提交读
提交读
可重复读
可串行读
 
 
3.3 游标事务隔离级别
通过结合游标并发设置的锁定状态、该游标 SELECT 中指定的任何提示,以及事务隔离级别选项,可以确定事务锁定的状态。
SQL Server支持下列游标事务隔离级别:
3.3.1 提交读
SQL Server 在将行读入游标期间,会获取一个共享锁,但在读完行之后会立即释放。因为排它锁会阻塞共享锁请求,所以游标无法读取其它任务已经更新但尚未提交的行。提交读是 SQL Server 和 ODBC的默认隔离级别设置。
3.3.2 未提交读
SQL Server 在将行读入游标期间不需要任何锁,并且不提供任何排它锁。游标可以使用已经更新但尚未提交的值来填充。在 SQL Server 中用户将绕过所有锁定事务控制机制。
3.3.3 可重复读或可串行读
如同 READ COMMITTED 中一样,在将行读入游标时,SQL Server 对每行都请求一个共享锁,但如果游标是在事务中打开的,则此共享锁将保持到事务结束,而不是在读取此行之后释放。这与在 SELECT 语句指定 HOLDLOCK 具有同样的效果。

 

注:本文是笔者2001年刚做程序员时写的笔记,近日整理资料时发现,就贴到Blog上,或者有参考作用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值