SQL Server事务、隔离级别详解(二十九)

本文详细介绍了SQL Server中的事务和隔离级别,包括原子性、一致性、隔离性和持续性的ACID属性。讲解了四种传统的悲观并发控制隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE,以及两种基于行版本控制的隔离级别:SNAPSHOT和READ COMMITTED SNAPSHOT。各个隔离级别之间的区别和应用场景,以及它们如何影响并发控制和数据一致性。
摘要由CSDN通过智能技术生成

前言

事务一直以来是我最薄弱的环节,也是我打算重新学习SQL Server的出发点,关于SQL Server中事务将分为几节来进行阐述,Always to review the basics。 

事务简介

事务是一个工作单元,可能包含查询和修改数据以及修改数据定义等多个活动。我们可以显式或隐式的定义事务边界。可以使用BEGIN TRAN或者BEGIN TRANSACTION语句显式的定义事务的开始。如果希望提交事务,可以使用COMMIT TRAN语句显式的定义事务结束。如果不希望提交事务(即要撤销更改),可以使用ROLLBACK TRAN或者ROLLBACK TRANSACTION语句-摘抄自SQL Server 2012基础教程。

如果不显式的标记事务的边界,默认情况下,SQL Server将把每个单独语句作为一个事务,换句话说,默认情况下,每个单独语句结束后SQL Server自动提交事务。可以通过一个叫做IMPLICIT_TRANSACTIONS的回话选项修改SQL Server处理隐式事务的方式,此选项默认为OFF。当此选项为ON时,不需要指定BEGIN TRAN语句标记事务的开始,但是必须以COMMIT TRAN或者ROLLBACK TRAN语句标记事务的结束-摘抄自SQL Server 2012基础教程。

事务具有原子性、一致性、隔离性、持续性四个属性,缩写字母为ACID。

(1)原子性:事务是一个工作单元,事务中的所有修改要么提交、要么撤销,在事务完成之前如果系统出现故障,重新启动时SQL Server会撤销所做的修改。

(2)一致性:一致性是指数据的状态,RDMS提供了以并发事务修改和查询数据的能力。

(3)隔离性:隔离是用于控制访问数据的机制,确保事务所访问数据是在其期望的一致性级别中的数据,SQL Server支持两种不同的模式来处理隔离:基于锁的传统模式和基于行版本控制的新模式,在企业内部部署的SQL Server中,默认是基于锁的模式。

(4)持续性:数据修改写入到数据库磁盘上的数据部分之前,总是先写入到数据库的事务日志磁盘,在提交之后,指令记录在事务日志的磁盘上,在尚未修改磁盘上的数据部分之前,事务被认为是持续的,在系统正常或是出现故障启动时,SQL Server将检查每个数据库的事务日志并执行具有两个阶段的恢复过程-重做和撤销。可以用如下图表示四个事务属性。

图片来源:https://blog.sqlauthority.com/2007/12/09/sql-server-acid-atomicity-consistency-isolation-durability/

说到事务就联想到并发,为了解决事务中的并发我们则不得不讨论下锁,所以接下来我们首先熟悉一下锁的模式-排他锁和共享锁。

排他锁:当试图修改数据时,事务会请求数据资源的一个排他锁,而不管其隔离级别,如果授予了锁,那么排他锁知道事务结束才会被解除,对于单语句事务意味着直到语句完成锁定才会被解除,对于多语句事务意味着直到完成所有语句并通过COMMIT TRAN或ROLLBACK TRAN命令结束才会解除锁定。排他锁之所以被称为排他,是因为如果一个事务正在修改行,直到事务完成,其他事务都不能修改相同的行,这是默认的修改行为。然而,另外一个事物能不能读取相同的行,取决于它的隔离级别。

共享锁:当试图读取数据时,事务默认请求数据资源的一个共享锁,并且一旦语句完成资源读取,会立即释放资源的共享锁。共享锁之所以被称为共享,是因为多个事务可以同时持有相同资源的共享锁。虽然在修改数据时,不能修改锁的模式和所需的持续时间,但是通过改变其隔离级别,可以在读取数据时控制锁定的处理方式。

讲述了锁的两种重要的模式,那么问题来了,锁的存在会导致什么问题?请继续往下看。我们试图去更新一条数据,此时并未进行提交

BEGIN TRAN

UPDATE Production.Products
    SET unitprice += 1.00
WHERE productid = 2

接下来我们再来读取该条记录的数据。

SELECT 
    productid, unitprice
FROM Production.Products
WHERE productid = 2

接下来我们进行查询,此时会发现一直在查询中直到达到设置的查询超时时间为止。

当更新行时会获取该资源上的排他锁,如果更新成功,SQL Server会将锁授予会话,所以直到事务完成,其排他锁会一直存在,当读取数据时需要获取该资源上的共享锁,但是更新行会话一直存在即以排他锁锁定,但是排他锁和共享锁不能兼容,此时会导致查询阻塞不得不进行等待。说明锁在并

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值