SQL Server中四类事务并发问题的实例再现

SQL Server事务、隔离级别和并发问题解决      版权声明:本文为博主原创文章,未经博主允许不得转载。    首先,对于SqlServer的事务和隔离级别,与其他关系型数据库类似,事务是一个工作单元,可能包含查询和修改数据以及修改数据定义等多个活动。我们可以显式或隐式的定义事务边界。可以使用BEGIN TRAN或者BEGIN TRANSACTION语句显式的定义事务的开始。如果希望提交事务,可以使用COMMIT TRAN语句显式的定义事... 阅读详情

SQL Server中四类事务并发问题的实例再现

朱二(2006.3 转载请注明作者)


  本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解。
  首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念。
在数据库中,假设如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括: 

  • 丢失或覆盖更新。
  • 未确认的相关性(脏读)。
  • 不一致的分析(非重复读)。
  • 幻像读。 
下面让我们稍花点时间来解释一下这四类问题:
1、丢失更新
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。


2、未确认的相关性(脏读)
当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。

3、不一致的分析(非重复读)
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。

4、幻像读
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。

  上述四个问题都会引起数据的不一致性。我们把事务准备接受不一致数据的级别称为隔离级别。隔离级别是一个事务必须与其它事务进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较高的隔离级别可以确保数据的正确性,但可能对并发产生负面影响。应用程序要求的隔离级别确定了  SQL Server  使用的锁定行为。

  SQL-92 定义了下列四种隔离级别,SQL Server 支持所有这些隔离级别:
  • READ UNCOMMITTED---未提交读(事务隔离的最低级别,仅可保证不读取物理损坏的数据)。
  • READ COMMITTED---提交读(SQL Server 默认级别)。
  • REPEATABLE READ---可重复读。
  • SERIALIZABLE---可串行读(事务隔离的最高级别,事务之间完全隔离)。
下表(1)列出了四种隔离级别允许不同类型的行为。
隔离级别脏读不可重复读取幻像
未提交读是是是
提交读否是是
可重复读否否是
可串行读否否否

为了再现以上四类问题,我们必须做一些准备工作:
1、请用下面的脚本创建测试用的表。
--创建测试用数据库test
CREATE DATABASE test
GO
--创建测试用表
USE test
GO
CREATE TABLE 帐户表
(
帐号 CHAR(4),
余额 INT
)
GO
INSERT 帐户表
SELECT 'A',100
UNION ALL
SELECT 'B',200


2、请开启两个查询分析器程序,意在开启两个连接,模拟两个并行的事务。以下简称连接一和连接二。
测试正式开始:
(1)丢失更新的再现

先看下面这个例子:
--在第一个连接中执行以下语句

BEGIN TRAN
UPDATE 帐户表 SET 余额=101 WHERE 帐号='A' 
WAITFOR DELAY '00:00:10' --等待10秒
COMMIT TRAN

--接着马上使用第二连接执行下面的语句

BEGIN TRAN
UPDATE 帐户表 SET 余额=102 WHERE 帐号='A' 
COMMIT TRAN


我们会发现第二个连接里面的事务不能立刻执行,必须等待第一连接的事务完成之后才能执行下去。
这样就避免了“丢失更新”的问题,否则的话就会产生“丢失更新”的问题了。

丢失更新的问题是最为严重的一类问题,由表一可知,无论使用哪一种事务隔离级别,都不允许丢失更新的问题,因此该类问题无法再现。

(2)未确认的相关性(脏读)的再现
由表1可知,当事务的隔离级别为未提交读(READ UNCOMMITTED)的时候,允许脏读。
--在第一个连接中执行以下语句

BEGIN TRAN
UPDATE 帐户表 SET 余额=103 WHERE 帐号='A' 
WAITFOR DELAY '00:00:10' --等待10秒
UPDATE 帐户表 SET 余额=104 WHERE 帐号='A'
COMMIT TRAN

--接着马上使用第二连接执行下面的语句
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
SELECT 余额 FROM 帐户表 WHERE 帐号='A' 
COMMIT TRAN


我们会发现第二个连接的语句会立即返回,结果是103,但遗憾的是它读取的是脏数据。
如果我们把第二个连接的事务隔离级别设置为 READ COMMITTED、REPEATABLE READ 或者SERIALIZABLE,都可以避免“脏读”的发生。

(3)不一致的分析(非重复读)的再现
由表1可知,当事务的隔离级别为未提交读(READ UNCOMMITTED)或者READ COMMITTED的时候,便可在现此问题。
请测试下面这个例子(假设帐号A的余额为100):
--在第一个连接中执行以下语句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
--或者 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
SELECT 余额 FROM 帐户表 WHERE 帐号='A'
WAITFOR DELAY '00:00:10' --等待10秒
SELECT 余额 FROM 帐户表 WHERE 帐号='A'
COMMIT TRAN

--接着马上使用第二连接执行下面的语句
BEGIN TRAN
UPDATE 帐户表 SET 余额=10 WHERE 帐号='A'
COMMIT TRAN

我们会发现第一个连接中两次返回帐号A的余额不一样,第一次是100,第二次返回的是10,这是典型的“非重复读”问题。
如果把连接一的事务隔离级别设置为REPEATABLE READ 或者SERIALIZABLE,可防止此类问题。


(3)不一致的分析(非重复读)的再现
由表1可知,当事务的隔离级别为未提交读(READ UNCOMMITTED)或者READ COMMITTED的时候,便可在现此问题。
先看下面这个例子(假设帐号A的余额为100):
--在第一个连接中执行以下语句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
--或者 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
SELECT 余额 FROM 帐户表 WHERE 帐号='A'
WAITFOR DELAY '00:00:10' --等待10秒
SELECT 余额 FROM 帐户表 WHERE 帐号='A'
COMMIT TRAN

--接着马上使用第二连接执行下面的语句
BEGIN TRAN
UPDATE 帐户表 SET 余额=10 WHERE 帐号='A'
COMMIT TRAN

我们会发现第一个连接中两次返回帐号A的余额不一样,第一次是100,第二次返回的是10,这是典型的“非重复读”问题。

如果把连接一的事务隔离级别设置为REPEATABLE READ 或者SERIALIZABLE,可防止此类问题。


(4)幻像读的再现
由表1可知,当事务的隔离级别为READ UNCOMMITTED或者READ COMMITTED或者REPEATABLE READ的时候,便可再现此问题。
先看下面这个例子(假设帐号A的余额为100):
--在第一个连接中执行以下语句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
--或者 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--或者 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT * FROM 帐户表 
WAITFOR DELAY '00:00:10' --等待10秒
SELECT * FROM 帐户表 
COMMIT TRAN

--接着马上使用第二连接执行下面的语句
BEGIN TRAN
INSERT INTO 帐户表 VALUES('C','300')
COMMIT TRAN

我们会发现第一个连接中在同一个事务中,同样的查询语句两次返回的结果集不一样,第二次返回的结果集中多了一条帐号为C的帐号,这是典型的“幻像读”问题。只有将连接一的事务隔离级别设置为SERIALIZABLE,才可防止此类问题。
  总结:为了避免事务并发带来的问题,可采用较高的事务隔离级别,但因此会降低事务的并行性;反过来如果追求高的并行性而使用较低的事务隔离级别,又容易带来并发的问题。因此SQL Server采用默认隔离级别是相对比较低的“READ COMMITTED”。在实际应用的时候,采用何种隔离级别视具体情况而定,也可以采用显式“上锁”的方法控制事务隔离级别,具体方法请留意笔者的相关文章。
详解一典型的反激式开关电源方案 如图,在某系统方案上看到下图所示的单端反激式开关电源方案。 阅读详情

相关推荐

嵌入式常见英文2500词总结

嵌入式常见英文总结

qq_28576837的博客 1万+

用MFRC522+STM32打造智能门禁:从硬件选型到云端控制全流程

本文详细介绍了基于STM32微控制器和MFRC522射频模块构建智能门禁系统的完整流程。从硬件选型、电路设计、底层驱动开发,到系统软件架构与状态机设计,并最终实现通过ESP8266模块接入云端平台(如OneNET)进行远程控制和数据可视化。项目深入探讨了MFRC522的SPI通信、卡片操作流程、天线调试以及云端MQTT集成等关键技术,为嵌入式开发者提供了一个从本地感知到云端管控的物联网项目实战参考。

raspberrypi5的博客 740

SQL Server数据库系列——锁和并发

最近在使用数据库,综合各方面原因,选择了SQL Server2008.为了对使用的工具有更加深入的了解,所以仔细地阅读了经典翻译书籍《SQL Server 2008高级程序设计》,在此将读书过程中的感想和理解记录下来,以备以后查询温习,也希望对其他使用SQL Sercer的小伙伴们有启发帮助。

walkman_lfq的博客 4979

UniTouch:多模态触觉对齐技术如何重塑零样本跨模态应用

UniTouch模型通过创新的多模态触觉对齐技术,成功将触觉数据映射到通用的视觉-语言嵌入空间,解决了触觉模态的“孤岛困境”。该技术利用对比学习和传感器特定标记,实现了高质量的零样本学习能力,使模型无需额外训练即可完成触觉分类、描述等任务,并能驱动跨模态生成,为机器人、VR和智能制造等领域提供了强大的触觉理解新范式。

weixin_29044713的博客 409

第三节: 串口通信(用CubeMX学习STM32)

用CubeMX学习STM32, 串口通信学习, 通过轮询方式和中断方式两种方式进行通信演示。 STM32F407zgt6

Kevin_8_Lee的博客 8903

SQL SERVER – High_CPU、阻塞请求、请求锁

SQL SERVER – Troubleshooting High CPU Performance Health Check. Step 1: Process Using CPU It is quite possible that your SQL Server is installed on the machine where there are other windows applications are also installed and they are consuming your CPU. W

qq_41290922的博客 269

激光打标轴坐标计算分析

‌:基于坐标差的平方和开方运算,勾股定理将几何关系转化为代数计算,从而实现了从坐标到距离的精确转换‌12。直角三角形的应用从上图可以看到A,B,P三个点连起来就是一个直角三角形了。用勾股定理计算距离 C#有相关的方法直接传参数就可以了。很方便。

StevenChen的博客 308

sqlserever数据库中两个事物同时对数据库执行select语句操作

因为DELETE和UPDATE都对数据库进行了修改,如与其他操作同时进行,容易造成对未提交数据的依赖;而SELECT不对数据库进行修改,因此两个SKLECT可以同时进行操作,而不会引起冲突。...

以梦为马 不负韶华 1227

从一个 ASIN 看透亚马逊:商品模型背后的增长飞轮

在亚马逊电商体系中,每件商品背后都有一套严密的商品建模逻辑。本篇文章以“ASIN 的一生”为线索,系统拆解了亚马逊的商品模型:从飞轮战略出发,剖析 SDP(Single Detail Page)机制如何实现标准化展示;再到 ASIN 编码、父子变体结构与 Offer 分离模型,逐层解析商品信息如何被建构、聚合与呈现。通过图解与案例,文章帮助读者理解商品建品流程、同款聚合原则、价格控制机制等核心逻辑,避免常见运营误区,是一份面向运营、产品、技术人员的实用参考指南。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 13万+

SAP 替代关系完全替代简介

这里产生了成品物料的计划订单,我们查看计划订单中BOM的变化,如下图可以看到物料的需求仍然落在了优先级为1的这个302300005555这个物料上面,并没有考虑到302300006666的这个库存,和我们理解的MRP的完全替代不一样,按我们的理解需求应该是要落在302300006666这个物料料,但是MRP计算后并没有这样进行分配。最近用户在对长周期物料进行备料的时候又提出替代料的问题,主料库存不足的时候需要考虑替代料的在途库存,经常会忘了SAP标准的替代料逻辑,这次一次性把这个逻辑写清楚。

我小时候很黑的博客 1738

[转]SQL Server中四类事务并发问题的实例再现

今天看到一篇很好的文章,转过来以做记录.原文地址为:http://blog.youkuaiyun.com/netcoder/archive/2006/03/23/633153.aspx 其中红字是我的标注. 本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解。   首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念。 在数据库中,假设如果没有锁...

anhai6033的博客 100

Flink Gauss CDC:深度剖析存量与增量同步的创新设计

开发Flink Gauss CDC是为了适配华为自研GaussDB的特殊日志格式和逻辑复制机制,解决Flink CDC无法直接支持的问题,同时优化存量与增量同步的效率和一体化读取能力,满足GaussDB复合主键处理、数据落库等定制化需求,以实现高效、准确的数据同步。

数据与算法架构提升之路专栏 1984

SQL Server中四类事务并发问题的实例再现(转)

  本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解。  首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念。在数据库中,假设如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括: 丢失或覆盖更新。 未确认的相关性(脏读)。 不一致的分析(非重复读)。 幻像读。...

dia6934的博客 162

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SQL Server中四类事务并发问题的实例再现(转)

<br />  <br />朱二(2006.3 转载请注明作者) <br />  本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解。<br />  首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念。<br />在数据库中,假设如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括:  丢失或覆盖更新。 未确认的相关性(脏读)。 不一致的分析(非重复读)。 幻像读。  下面让我们稍花点时间来解释一下这四类问

xuwei88668866的专栏 211

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

SQL Server中的事务(附有实例)

一、事务 定义: 例如: 在银行活动中,“由账户A转移资金额X到账户B”是一个典型的银行数据库业 务。这个业务可以分解为两个动作: 1)从账户A中减掉金额X 2)在账户B中加入金额X 这两个动作应当构成一个不可分割的整体,要么完成其中...

legendaryhaha的博客 3万+

SQL Server中四类事务并发问题的实例

 本篇文章将用实例再现数据库访问中四类并发问题,希望能让初学者能对事务的并行性有进一步的理解。   首先,让我们先来了解一下并行问题以及事务隔离级别这两个概念。 在数据库中,假设如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括: 丢失或覆盖更新。

bingbing200x的专栏 1657

SQL SERVER 事务简介及使用实例

sql server 常见的三种事务:自动提交事务,显式事务和隐式事务........

MrLsss的博客 2326

sql server 并发_并发问题– SQL Server中的理论和实验

sql server 并发 介绍 (Introduction) Intended audience 目标听众 This document is intended for application developers and database administrators who are willing to get an overview of comm concurrency ...

culuo4781的博客 955

sql server事务隔离别 、 mysql 事务隔离级别、并发性问题

事务隔离级别是数据库管理系统中用来控制并发访问的一种机制。它定义了在一个事务中所做的修改对其他事务的可见性,以及其他事务对当前事务的影响程度。未提交读(Read Uncommitted)已提交读(Read Committed)可重复读(Repeatable Read)串行化(Serializable)事务隔离级别是数据库管理系统中控制并发访问的一种机制,SQL Server 提供了四种事务隔离级别:未提交读、已提交读、可重复读和串行化。

杨思默 1009

SQL Server中四类事务并发问题

最近在网上看到一篇关于讲"SQL Server中四类事务并发问题"的帖子,不错就转载过来。 原帖地址是:http://blog.youkuaiyun.com/netcoder/archive/2006/03/23/633153.aspx 本篇文章将用实例再现数据库访问中四类并发问

706
上一篇: 我所理解的设计模式(C++实现)—— “一句话总结”和索引
下一篇: 最佳实践:C#项目转C++项目
十八道胡同
博客等级 码龄20年 848粉丝 109原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值