事务的并发操作可能出现的问题

中文 英文 描述
脏读 Dirty Reads 事务2读到了事务1未提交的事务,事务1随后回滚,但事务2读到了事务1的“中间数据”。 在Read Uncommitted隔离级别下会发生,其它级别不会。
(update&read)
丢失更新 Lost Updates 两个事务对同一个行分别进行更新,其中一个更新覆盖了另一个,导致丢失了一个更新。 在Read Committed的隔离级别下仍能发生,Repeatable Read能够避免它发生。
为什么官方文档里没有提到Lost Updates这个现象?
官方文档:Transaction Isolation Levels
(read&update)
不可重复读 Non-repeatable Reads 事务2在事务1的两次读取之间更新了数据导致事务1两次读到不一样的数据。 在Repeatable Read隔离级别下解决,和Lost Update一样,本质都是因为在此隔离级别下S锁持有到事务结束使其它事务无法在本事务执行过程中更新数据。
(read&update)
幻读 Phantom Reads 当一个事务执行一个query两次, 但得到不同行数的结果集。 幻读和不可重复读不一样地方在于,解决不可重复读问题时针对的是已有数据,因此可以持有它们的S锁,使其它事务请求X锁时等待;而幻读是新插入的数据。
(insert\delete)

事务

  • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。

我一直纳闷这个“一致”是什么意思,然后在#引用.1.这本书里看到了解释:数据库在某一时刻的状态反应的是真实世界在这个时刻的数据,真实世界被抽象成数据,然后真实世界不停运行,数据库中的数据就像真实世界的一个切面,只不过真实世界是连续的,而数据库的数据是真实世界某一个时刻的状态,是离散的。随着真实世界的运行,当数据库中的数据从一个时刻到下一个时刻且数据都是“正确的”的时候,就称数据库从一个一致性状态到了另一个一致性状态,保证这种“一致性”的手段就是“数据库约束”,它对数据的正确性进行校验。不过,这种校验是片面的,数据的正确性也取决于业务逻辑(后台代码),但在数据库层面能做的就是“数据库约束”。

  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

  • 持久性(Durability):即便发生断电等意外情况,已被提交的事务对数据库的修改应该永久保存在数据库中(硬盘上)。这点一般通过日志来保证。

事务的隔离级别

隔离级别影响锁模式的表现。

Read Uncommitted

  • 不要求SELECT时请求S锁,因此它不会阻塞X锁或者被X锁阻塞,因此可以发生脏读。

  • The intention of this isolation level is for systems primarily focused on reporting and business intelligence, not online transaction processing.

  • 别用。

Read Committed

  • 要求SELECT时请求S锁,因此它会阻塞X锁或者被X锁阻塞,因此可以避免脏读。

  • 它是SQL Server默认的隔离级别。

  • 由于S锁不会持有到事务结束,而是在SELECT完成后就释放了, 因此可能发生幻读和不可重复读。

    • 幻读:INSERT, DELETE

    • 不可重复读:UPDATE

Repeatable Read

  • 要求SELECT时请求S锁,并持续到事务结束,因此避免了事务过程中其它事务对数据的修改,因此可以避免幻读和不可重复读。

  • 可重复读:在当前的事务中可再次读取(R),读取的结果没有被修改(CUD)。

Serializable

  • 最高级别的隔离级别

  • 相比直接在所需的行上加锁,可串行化隔离级别在所需的行和下一行(索引顺序)上获得一个range lock。因此它可以避免插入新的数据,从而避免幻读现象。

  • 上图是SQLite中的页的结构,但DBMS设计思路是类似的。在一个页中,存储着多个Key,这些Key按顺序排列在一个数组中,所谓的“下一个”就是这个索引的下一个。

  • 如果key存在

    • 如果next key存在:

      • 在non-unique index的情况下,在当前请求的key和next key上范围锁。
      • 在unique index的情况下,理论上在key上获取S锁就足够,但SQL Server仍会获取范围锁
    • 如果next key不存在:taken on the ‘infinity’ value.
  • 如果key不存在

    • 如果next key存在:taken on the next key.
    • 如果next key不存在: taken on the ‘infinity’ value.
  • 在无限大上的范围锁会锁定 >= 当前key的范围

  • BETWEEN 在请求的key上和next key上获取范围锁

  • WHERE 在请求的key及前后获取范围锁

create table foo (c1 int)

go

insert into foo values (1)

insert into foo values (2)

insert into foo values (3)

insert into foo values (4)

insert into foo values (5)

create unique clustered index foo_ci on foo(c1)

set tran isolation level serializable

begin tran

select * from foo where c1 between 2 and 4 

SELECT dtl.request_session_id,
dtl.resource_database_id,
dtl.resource_associated_entity_id,
dtl.resource_type,
dtl.resource_description,
dtl.request_mode,
dtl.request_status
FROM sys.dm_tran_locks AS dtl
WHERE dtl.request_session_id = @@SPID;

引用

  1. 《SQL Server 2017 Query Performance Tuning 5th Edition》
  2. dotnettutorials: sql-server-concurrent-transactions
  3. stackoverflow: what are range locks
  4. techcommunity.microsoft: SQL Server Range Lock
  5. Microsoft: Transaction Isolation Levels

SQL Server事务及隔离级别的更多相关文章

  1. SQL Server事务的隔离级别

    SQL Server事务的隔离级别 ########## 数据库中数据的一致性 ########## 针对并发事务出现的数据不一致性,提出了4个级别的解决方法:  隔离级别  第一类丢失更新  脏读 ...

  2. SQL Server事务的隔离级别和锁

    背景        当用户并发尝试访问同一数据的时,SQL Server尝试用锁来隔离不一致的数据和使用隔离级别查询数据时控制一致性(数据该如何读取),说起锁就会联想到事务,事务是一个工作单元,包括查 ...

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

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

  4. SQL Server 事务与隔离级别实例讲解

    上班途中,你在一处ATM机前停了下来.正当你在敲入密码的时候,你的一位家人也正在镇上的另一处TAM机上输入密码.你打算从某个还有500元余额的账户上转出400元,而你的家人想从同一账户取走300元.倘 ...

  5. SQL SERVER 2008 数据库隔离级别代码演示

    SQL SERVER 2008 数据库隔离级别代码演示   个隔离级别(其实这是SQL 工业标) 种隔离级别,本身没有优劣之分,完全取决于应用的场景. 本质上,他们是在 隔离性(紊乱程度) 和 灵活性 ...

  6. SQL Server 事务隔离级别详解

    标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设置数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一 ...

  7. SQL Server 事务隔离级别

    一.事务隔离级别控制着事务的如下表现: 读取数据时是否占用锁以及所请求的锁类型. 占用读取锁的时间. 引用其他事务修改的行的读操作是否: 在该行上的排他锁被释放之前阻塞其他事务. 检索在启动语句或事务 ...

  8. 【转】SQL Server 事务隔离级别详解

    SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可 ...

  9. SQL Server 之 事务与隔离级别实例讲解

    SQL Server 之 事务与隔离级别实例讲解 SQL Server 实现了6个隔离级别来防止并发情况下,类似企图并发的访问或修改同一数据时问题的发生.本文将带你体验全部6个隔离级别.正如你接下来将 ...

  10. SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

随机推荐

  1. 初识常量变量、字符串、ASCII编码表、转义字符表

    一.常量.变量 1.枚举常量(enum) 枚举常量不能更改,枚举常量所创造出的变量可以更改 正确 错误 2.常变量 3.#define定义的标示变量 二.数组 "abc"--'a' ...

  2. SEO相关配置 HTML meta标签总结与属性使用介绍

    HTML meta标签总结与属性使用介绍 <!-- 声明文档使用的字符编码 --> <meta charset='utf-8'> <!-- 优先使用 IE 最新版本和 C ...

  3. Mysql高级2-SQL性能分析

    一.SQL执行频率 MySQL客户端 连接成功后,通过show [session | global] status 命令可以提供服务器状态信息,通过如下指令,可以查看当前数据库的insert,upda ...

  4. 隐藏tkinter弹出的创库

    1 import tkinter as tk 2 root = tk.Tk() 3 root.withdraw()

  5. python excel 07版本转换为03版本

    需要安装pywin32模块 pip install pywin32 主程序: import win32com.client as win32 import os.path import glob cl ...

  6. 安装 配置 正向 解析 DNS方法

    安装 配置 正向 解析 DNS方法 1,安装dhcp [root@localhost ~]#yum install bind* -y 2,关闭防火墙和selinux [root@localhost ~ ...

  7. 《UNIX 传奇:历史与回忆》读后感

    <UNIX 传奇:历史与回忆> 是 bwk(Brian W. Kernighan)2019 年的新作,回忆了 UNIX 在大半个世纪的风雨历程,是一本引人入胜的书籍.通过对 UNIX 操作 ...

  8. [django]路由变量与正则表达式

    示例: urlpatterns = [ path('detail.<int:id>.html', detailView, name='detail'), ] 路由变量的类型 示例路由配置了 ...

  9. 论文解读(SimGCL)《Are Graph Augmentations Necessary? Simple Graph Contrastive Learning for Recommendation》

    Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Are Graph Augmentations Necessary? Simple Graph Contr ...

  10. 从头到尾说一次 Spring 事务管理(器)

    事务管理,一个被说烂的也被看烂的话题,还是八股文中的基础股之一.​ 本文会从设计角度,一步步的剖析 Spring 事务管理的设计思路(都会设计事务管理器了,还能玩不转?) 为什么需要事务管理? 先看看 ...