SQL SERVER技术内幕之10 事务并发
1.事务
1.1事务的定义
事务是作为单个工作单元而执行的一系列操作。定义事务边界有显式和隐式两种。显式事务的定义以BEGIN TRAN作为开始,以COMMIT TRAN提交事务,以ROLLBACK TRAN撤销事务。如果不显式定义事务的边界,SQL Server会默认把每个单独的语句作为一个事务。也就是说,SQL Server默认在执行完每个语句之后就自动提交事务。可以通过IMPLICIT_TRANSACTIONS会话选项来改变SQL Server处理隐式事务的方式。
1.2事务的属性
(1)原子性:事务必须是原子工作单元,这意味着在事务中进行的修改,要么全都执行,要么全都不执行。
(2)一致性:同时发生的事务在修改和查询数据时不发生冲突,通过RDBMS访问的数据要保持一致的状态。
(3)隔离性:隔离性是一种用于控制数据访问的机制,能够确保事务只访问处于期望的一致性级别下的数据。
(4)持久性:在将数据修改写入到磁盘上数据库的数据分区之前,总是先把这些修改写入到磁盘上数据库的事务日志中。
2.锁定和阻塞
2.1锁
锁是事务获取的一种控制资源,用于保护数据资源,防止其他事务对数据进行冲突的或不兼容的访问。
(1)锁模式及其兼容性
排他锁:对于相同的数据类型,如果有其他事务已经获得了该资源其他类型的锁,就不能再获得该资源的排他锁。如果有其他事务已经获得了该资源的排他锁,就不能再获得该资源的任何类型的锁。当试图修改数据时,事务会为所依赖的数据资源请求排他锁。这是修改行为的默认处理方式,而且这种默认行为不能改变,不能改变为修改数据资源而请求的锁模式(排他锁),也不能改变持有锁的时间长度(直到事务完成)
共享锁:多个事务可以同时持有同一数据资源上的共享锁。当试图读取数据时,事务默认会为所依赖的数据资源请求共享锁。读取操作一旦完成,就即释放资源上的共享锁,虽然当修改数据时不能改变请求的锁模式和持续时间,但当读取数据时可以对如何处理锁定进行控制。
(2)可锁定资源的类型
SQL Server可以锁定不同类型或粒度的资源,这些资源类型包括行、页、对象(例如表)、数据库等。行位于页中,而页则是包含表或索引数据的物理数据块。为了获得特定资源类型上的锁,事务必须先在更高的粒度级别上获得相同模式的意向锁,例如,为了获得某一行的排他锁,事务必须先在包含那一行的页上获取意向排他锁。同样,要获得某一粒度级别上的共享锁,事务就必须先在更高的粒度级别上获取意向共享锁。意向锁的目的是为了在较高的粒度级别上有效地检测不兼容的锁定请求,防止授予不兼容的锁。例如一个事务持有一个行锁,而其他事务想在包含那一行的整个页或表上请求不兼容的锁模式,这时SQL Server可以很容易地识别出这种冲突。意向锁不会干预较低粒度上的锁定请求,一个页上的意向锁不会阻止其他事务在该页内的行上获取不兼容的锁模式。
SQL Server动态决定应该锁定哪种类型的资源。自然,为了获得理想的并发性,最好是只锁定需要的资源,即只锁定受影响的行。但是,锁定需要占用内存资源和内部的管理开销,所以SQL Server在选择锁定哪种类型的资源时会同时考虑并发性和系统资源。SQL Server会先获得细粒度的锁(例如行或页),在某些情况下再尝试将锁升级为更粗粒度的锁例(如表)。例如当单个语句获得至少5,000个锁时,就会触发锁升级。
3.隔离级别
隔离级别用于决定如何控制并发用户读写数据的操作。对于操作获得的锁以及锁的持续时间来说,虽然不能控制写操作的处理方式,但可以控制读操作的处理方式。当然,作为 对读操作的行为进行控制的一种结果,也将隐含地影响写操作的处理方式。可以在会话级别或查询级别来设置隔离级别。
要设置整个会话的隔离级别,可以使用以下命令:
SET TRANSACTION ISOLATION LEVEL <isolation name>;
要可以使用表提示来设置查询的隔离级别:
SELECT … FROM <table> WITH (<isolationname>)
默认的隔离级别是READ COMMITTED。如果你选择修改这个默认的级别,那么选择的结果对数据库用户的并发性和他们获取数据的一致性都会产生影响。对于SQL Server 2005之前可用的四个隔离级别(如下所示的前4个隔离级别),隔离级别越高,读操作请求的锁定就越严格,锁持有的时间也就更长,因此,隔离级别越高,一致性也就越高,并发性也就越低。
(1)READ UNCOMMITTED 未提交读
在这个隔离级别运行的事务,读操作不会请求共享锁。这意味着读操作可以读取未提交的修改(脏读)
(2)READ COMMITTED(默认) 已提交读
如果想避免读取未提交的修改,则需要使用要求更严格的隔离级别。能够防止脏读的最低隔离级别是READ COMMITTED,这也是所有版本的SQL Server默认使用的隔离级别。这个隔离级别只允许读取已经提交过的修改。它要求读操作必须获得共享锁才能进行操作,从而防止读取未提交的修改。
按照锁的持有时间来说,在READ COMMITTED隔离级别中,读操作一完成,就立即释放资源上的共享锁,这意味着在一个事务处理内部对相同数据资源的两个读操作之间,没有共享锁会锁定该资源,其他事务可以在两个读操作之间更改数据资源,读操作因而可能每次得到不同的取值。这种现象称为不可重复读或不一致的分析。
(3)REPEATABLE READ 可重复读
如果想保证在事务内进行的两个读操作之间,其他任何事务都不能修改由当前事务读取的数据,则需要把隔离级别升级为REPEATABLE READ.在这种隔离级别下,事务中的读操作不但需要获得共享锁才能读取数据,而且获得的共享锁将一直保持到事务完成为止。
REPEATABLE READ隔离级别能够防止的另一种并发负面影响是丢失更新,而较低的隔离级别则不能防止这种问题。因为在比REPEATABLE READ更低的隔离级别中,读取完数据之后就不再持有资源上的任何锁,两个事务都能更新这个值,而最后进行更新的事务则是”赢家”,覆盖由其他事务所作的更新,这将导致数据丢失。
(4)SERIALIZABLE可序列化
在REPEATABLE READ隔离级别是运行的事务,读操作获得的共享锁将一直保持到事务完成为止。因此可以保证在事务中第一次读取某些行后,还可以重复读取这些行。但是,事务只锁定查询第一次运行时找到的那些数据资源,而不会锁定查询结果范围以外的其他行。因此,在同一事务中进行第二次读取之前,如果其他事务插入了新行,而且新行也能满足读操作的查询过滤条件,那么这些新行也会出现在第二次读操作返回的结果中,这些新行称为幻影。
SERIABLIZABLE与REPEATABLE READ类似:却读操作需要获得共享锁才能读取数据,并保留共享锁直到事务完成。不过,SERIALIZABLE隔离级别增加了一个新内容:逻辑上,这就意味着读操作不仅锁定了满足查询搜索条件的现有的那些行,还锁定了未来可能满足查询搜索条件的行。
4.死锁
死锁是指一种进程之间互相永久阻塞的状态,可能涉及两个或更多的进程。
SQL SERVER技术内幕之10 事务并发的更多相关文章
- SQL SERVER技术内幕之10 可编程对象
一.变量 变量用于临时保存数据值,以供在声明它们的同一批处理语句中引用.例如,以下代码先声明一个数据类型为INT的变量@i,再将它赋值为10; DECLARE @i as INT; SET @i = ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- SQL SERVER技术内幕之6 集合查询
1.定义 集合运算会对两个输入查询的结果集进行逐行比较,根据比较结果和所使用的集合运算来确定某一行是否应该包含在集合运算的结果中.因为集合运算是针对集合之间进行的计算,所以集合运算涉及的两个查询不能包 ...
- SQL SERVER技术内幕之8 分组集
分组集就是分组(GROUP BY子句)使用的一组属性,在传统的SQL中,一个聚合查询只能定义一个分组集: 假设现在不想生成4个单独的结果集,而是希望生成一个统一的结果集,其中包含所有4个分组集的聚合 ...
- SQL SERVER技术内幕之5 表表达式
表表达式是一种命名的查询表达式,代表一个有效的关系表.可以像其他表一样,在数据处理语句中使用表表达式.SQL Server支持4种类型的表表达式:派生表(derived table).公用表表达式(C ...
- SQL SERVER技术内幕之3 联接查询
JOIN表运算符对两个输入表进行操作.联接有三种基本类型:交叉联接.内联接和外联接.这三种联接的区别是它们采用的逻辑查询处理步骤各不相同,每种联接都有一套不同的步骤.交叉联接只有一个步骤----笛卡尔 ...
- SQL SERVER技术内幕之7 透视与逆透视
1.透视转换 透视数据(pivoting)是一种把数据从行的状态旋转为列的状态的处理,在这个过程中可能须要对值进行聚合. 每个透视转换将涉及三个逻辑处理阶段,每个阶段都有相关的元素:分组阶段处理相关的 ...
- SQL SERVER技术内幕之4 子查询
最外层查询的结果集会返回给调用者,称为外部查询.内部查询的结果是供外部查询使用的,也称为子查询.子查询可以分成独立子查询和相关子查询两类.独立子查询不依赖于它所属的外部查询,而相关子查询则须依赖它所属 ...
- SQL SERVER 查询性能优化——分析事务与锁(五)
SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...
随机推荐
- 第1天 Java基础语法
Java基础语法 今日内容介绍 Java开发环境搭建 HelloWorld案例 注释.关键字.标识符 数据(数据类型.常量) Java开发环境搭建 Java概述 众所周知Java是一门编程语言,编程语 ...
- 使用bison和yacc制作脚本语言(3)
我们现在已经可以写好文法了,下一步我们打算开始正式创建工程了 在工程目录下,我们创建如下文件夹 ./include ./memory ./ms include文件夹下我们将放头文件 memory是内存 ...
- gsl 复数
一.复数的表示 复数的两种表示: gsl复数结构的声明和部分宏在gsl_complex.h中,方法的声明和另一部分宏在gsl_complex_math.h.复数的表示(结构)有三种,即float型.d ...
- 破解使用SMB协议的Windows用户密码:acccheck
一.工作原理 Acccheck是一款针对微软的SMB协议的探测工具(字典破解用户名和密码),本身不具有漏洞利用的能力. SMB协议:SMB(Server Message Block)通信协议主要是作为 ...
- 成都Uber优步司机奖励政策(2月2日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 使用postman实现半自动化
前些日子项目要上一个活动,其中有一个功能是幸运大转盘,用户可以随机抽奖,奖品有多种满减券及多种商品,但是奖品都是有抽中概率的,且有的商品还设置有库存,所以测试点便是测试抽奖的概率和库存.接下来拆分一下 ...
- 【SpringCloud 】第八篇: 消息总线(Spring Cloud Bus)
前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...
- Objective-C Block数据类型 @protocol关键字
Block数据类型 Block封装了一段代码 可以在任何时候执行 Block可以作为函数参数或者函数的返回值 而其本身又可以带输入参数或返回值 苹果官方建议尽量多用Block 在多线程 异步任务 集合 ...
- Oracle-数据库增删改查基本操作
一.创建数据表 1).创建不存在的新表: create table tname( Data_Name Date_Type [default][默认值] );2).创建已存在表的副本 create ...
- 剑指offer-二叉树搜索树与双向链表25
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. class Solution: def Convert(self, pRo ...