事务是什么

  在SQL Server中事务是构成一个工作逻辑单元的一系列任务,也就说多个任务放在一起执行,这些任务要么全部执行成功,要么全部执行失败。

  通过事务我们可以保证数据的完整性,例如:用户A给用户B转1000块钱,如果从用户A的账号中扣了1000块,但是在向用户B账号添加1000块的时候执行失败,这个时候用户A说自己转了,用户B却有没收到,两个还不得打起来。所以针对于这种情况,需要使用事务,其中从用户A账号扣除1000块钱是一个任务,向用户B账号添加1000块是另一个任务,这两个任务如果都执行成功说明转账成功,如果都执行失败,这1000块还在用户A账上。

ACID属性

  在了解事务之前,我们还是要先了解一些基本概念。

  事务必须满足一组需求,称之为ACID属性,分别指的是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

  原子性

  根据我们学过的化学知识,分子是原子组成,而原子是不可再分的,正如开篇对事务的定义,事务里面的任务只能全部执行成功或全部不执行这两种结果,如果只有部分任务执行成功,就违反了原子属性。

  一致性

  事务必须保证数据的一致性,虽然在事务处理期间内允许数据库处于不一致的状态下,但是在事务完成时必须是一致的。

  例如,假设Orders表和OrderDetails表之间存在一个基于OrderID字段的外键,这个约束确保OrderDetails表中存在OrderID之前,该OrderID必须先存在于Orders表中。如果一个事务如果没有Orders表写入记录,但给OrderDetails表写入了记录,数据库就处于不一致的状态。

  隔离性

  每个事务都是隔离的,隔离有不同的隔离级别,后面会详细讲解。

  持久性

  事务的持久性是指事务提交之后,就保持这个状态,即如果事务修改了某行数据,这个事务提交之后,这个事务就不会再改变该行数据,除非再次执行事务。

如果使用事务

  在SQL Server主要使用下面三个命令实现事务的编程:

  Begin Transaction:开始事务

  Commit Transaction:提交事务

  Rollback Transaction:回滚事务

  一旦开始事务,要么提交,要么回滚,否则已开始的事务在事务处理期间会一直保持锁定,可能阻塞其他事务的执行。简单示例如下:

Begin Try
Begin Transaction
select departmentId as DeptId,Name
from HumanResources.Department
where name between 'A' And 'G' Commit transaction End Try
Begin Catch;
Rollback Transaction
Return;
End Catch;

理解SQL Server锁定

  SQL Server使用锁实现ACID隔离属性,锁确保一个事务的修改不受另一个事务修改事务的影响,锁定数据也存在不同的级别。

  按粒度划分

  行锁:锁定单行,这是最小的锁

  页面锁:锁定一页或8KB,一个页存在一行或多行

  区锁:锁定8个页面或64KB

  表锁:锁定整个表

  数据库锁:锁整个数据库,这个锁主要用于架构更改时

  键锁:锁索引上的节点

  SQL Server会自动管理锁的大小,尽可能使用较小的锁,因为较小的锁允许更多的事务访问数据,另外,每个锁都需要在内存中保存锁的信息,所以锁越少越好。SQL Sever在检测到内存压力时,会提升锁的级别。

  按模式划分

  共享锁:

  数据库默认的隔离级别使用的就是共享锁,即多个进程同时拥有,因为是大家的,所以只能看不能改,而且共享锁不能用于当前正在修改的行/页面/表上。

  排他锁:

  顾名思义,就是我的东西,不允许别人看,更不允许修改,通常在事务对数据执行写入时使用排它锁。

  更新锁:

  更新锁意味着,事务准备执行排他锁,当前正在扫描数据,以确定它希望锁定的行。可以简单看成,打算转变为排它锁的共享锁。

  

  按模式划分,还有其他类型,例如:意向共享锁、意向排他共享锁、意向排他锁。

事务隔离级别

  在了解事务的隔离级别之前,必须先明白三个概念:脏读取、不能重复的读取和幻影行。

  脏数据

  所谓的脏数据,其实值得就是还没有其他的数据,即没有正真写入到数据库的数据。那么这样的数据是怎么来的呢?

  通常,脏数据是由其他事务产生,但是在该事务并未提交,而这数据已经被其他事务获取使用,显然这样的数据是有问题的。

  不能重复的读取

  简单的理解,就是第一次执行事务(但未提交)和第二次执行该事务获取到的数据不一样,即第二次事务开始之前,数据被修改了,当然在一般情况下这样的数据没问题,但是对于一些隔离级别要求很高,就要求两次执行相同的事务获取的结果必须一样,即重复的。

  幻影行

  重复的读取,指定是选中的行,这个行是确定的,但是有时事务获取的是一个行范围,在第一次执行事务(但未提交)和第二次执行该事务获取的行范围就可能存在不同,为啥呢?因为别的事务可能会去新增或删除行,而这些行我们叫做幻影行。

  了解这些基本概念之后,我们看看具体事务的隔离级别。

  级别1——Read Uncommitted

  这是最低级别的隔离,允许读取没有提交的事务修改的数据,即上面说的脏数据。这个级别在读取数据的时候不设置共享锁。

  示例如下:

set Transaction Isolation level Read Uncommitted

  Begin Transaction
update HumanResources.Department
set Name='ABC ddd'
Where DepartmentID=1 Commit transaction

  级别2——Read Committed

  SQL Server中默认的事务隔离级别就是Read Committed,确保一个事务不能读取另外一个事务已修改但未提交的数据。

  级别3——Repeatable Read

  在Repeatable Read中,任何在事务处理过程中获得的共享锁都会保持下去,直到事务提交为止。这不同于Read Committed隔离级别,Read Committed只在正在读取的数据上拥有共享锁。Repeatable Read级别能够保证读取到重复的数据。

  级别4——Serializable

  这个最严格的隔离级别禁止出现所有的事务错误:脏数据、不可重复的读取和幻影行。

  这个隔离级别可用于绝对事务完整性比性能更重要的数据库。银行、会计和竞争激烈的销售数据库(如股票市场)。

SQL Server中事务、锁定和阻塞的更多相关文章

  1. SQL Server中SELECT会真的阻塞SELECT吗?

    在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...

  2. 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

    SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列   本文是Stairway系列的一部分:SQL ...

  3. SQL Server中事务日志管理的步骤,第5级:完全恢复模式管理日志(译)

    SQL Server中事务日志管理的步骤,第5级:完全恢复模式管理日志 作者:Tony Davis,2012/01/27 系列 本文是进阶系列的一部分:SQL Server中事务日志管理的步骤 当事情 ...

  4. SQL server中事务的四个属性特征(ACID)

    事务的概念.类型和四个特征(ACID). 1.事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位. 通过事务,SQL Se ...

  5. SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

    假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...

  6. Sql Server 中事务(begin tran/commit tran/rollback tran)的用法

    ALTER PROCEDURE [dbo].[Proc_Test_commit1]     @result int output, --成功 1; 失败 0     @message nvarchar ...

  7. SQL Server中的事务与锁

    了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...

  8. 【转】SQL Server中的事务与锁

    SQL Server中的事务与锁   了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...

  9. SQL Server中锁与事务隔离级别

    SQL Server中的锁分为两类: 共享锁 排它锁 锁的兼容性:事务间锁的相互影响称为锁的兼容性. 锁模式 是否可以持有排它锁 是否可以持有共享锁 已持有排它锁 否 否 已持有共享锁 否 是 SQL ...

随机推荐

  1. github安装&初探

    主要记录安装中的问题: 1 centos 5和6的epel源需要不同的包来更新 Centos 5.x wget http://dl.fedoraproject.org/pub/epel/5/x86_6 ...

  2. 链表原地反转Demo

    现在就是Qt开发和给师弟师妹讲下数据结构吧,感觉还挺漫长的,上个Qt帖子等我把成品做出来再更. //Convert_plug.h #ifndef CONVERT #define CONVERT #de ...

  3. C Primer Plus_第5章_运算符、表达式和语句_编程练习

    Practice 1. 输入分钟输出对应的小时和分钟. #include #define MIN_PER_H 60 int main(void) { int mins, hours, minutes; ...

  4. .NET LINQ 串联运算

    串联运算      串联是指将一个序列追加到另一个序列的运算. 方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表达式语法 更多信息 Concat 串联两个序列以组成一个序列. ...

  5. iOS 设置非ARC类

    用-fno-objc-arc标记来禁用在ARC工程那些不支持ARC的文件的ARC用-fobjc-arc标记启用非ARC工程中支持ARC的文件

  6. JVM 1.6 GC

    JVM调优是一门艺术. JVM调优的重点是减少Major GC的次数,因为Major GC会暂停程序比较长的时间.如果Major GC的次数比较多,意味着应用程序的JVM内存参数需要调整. JVM内存 ...

  7. 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵

    题目描述: 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积) 输入: 每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K 接下 ...

  8. BestCoder Round #85(ZOJ1569尚未验证)

    A题 子序列和啊,就要想到前缀和的差.这个转换一定要!记着!那么i到j的一段子序列和Sij%m ==  0就等价于(Sj-Si-1)%m == 0 了,那么什么意思呢?就是如果有两段前缀和%m的模是一 ...

  9. WebForm控件Repeater

    我们会发现用拼接字符串来显示一个查询非常的麻烦,有一个控件Repeater帮助你,省去写Foreach LinQ to SQL类 函数类: using System; using System.Col ...

  10. C# WinForm 慎用 override CreateParams 来重载窗体的一些特性

    窗体和控件的属性CreateParams(这真的是一个属性)很神奇,因为通过它你能够很方便的控制窗体或控件诸如边框.最大化最小化关闭按钮的隐藏.窗体的模式化弹窗模式等的一些特性.虽然,CreatePa ...