百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

数据库事务的隔离级别(数据库事务隔离级别和锁的对应关系)

mhr18 2024-09-18 20:23 22 浏览 0 评论

目录

数据库事务的隔离级别2

数据库ACID理论2

原子性2

一致性2

隔离性2

持久性3

事务隔离级别3

Read Uncommitted(读取未提交内容)3

Read Committed(读取提交内容)3

Repeatable Read(可重读)3

Serializable(可串行化)3

隔离级别的实现 4

一致性4

业务一致性5

幂等性(idempotent)5

业务一致性(Consistency)5

可串行化(Serializable)6

参考6


数据库ACID理论

在数据库系统中,一个事务是指由一系列数据库操作组成的一个完整的逻辑过程。例如银行转帐,从原账户扣除金额,以及向目标账户添加金额,这两个数据库操作的总和构成一个完整的逻辑过程,不可拆分。这个过程被称为一个事务,须满足ACID特性。

  • ACID特性[1]是指在数据库管理系统(DBMS)中事务所具有的四个特性,它们分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

原子性

原子性是指事务是一个不可再分割的工作单元,事务中的操作要么都发生,要么都不发生。

  • 在DBMS中,默认情况下一条SQL就是一个单独事务,事务是自动提交的。只有显式的使用start transaction开启一个事务,才能将一个代码块放在事务中执行。

一致性

一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。

  • 数据库层面会在一个事务执行之前和之后,确保数据符合设置的约束(唯一约束,外键约束,check约束等)和触发器设置;此外,数据库的内部数据结构(如 B 树索引或双向链表)都必须是正确的。业务的一致性一般由开发人员进行保证,亦可转移至数据库层面。

隔离性

多个事务并发访问时,事务之间是隔离的,一个事务不应影响其它事务运行效果。

在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

事务最复杂问题都是由事务隔离性引起的。完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样会严重影响性能。

  • 隔离性中的事务隔离等级是本文要详细分析的。

持久性

  • 持久性,意味着在事务完成以后,该事务所对数据库所作的更改要持久的保存在数据库之中,并不会被回滚。(完成的事务是系统永久的部分,对系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持)

事务隔离级别

  • SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

Read Uncommitted(读取未提交内容)

  • 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

Read Committed(读取提交内容)

  • 这是大多数数据库系统的默认隔离级别(比如SqlServer,但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

Repeatable Read(可重读)

  • 这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

  • 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

隔离级别的实现

以上隔离级别是SQL标准的定义。不同的数据库厂商对隔离级别的实现并不一致,如SQL Server[2], DB2[3],Oracle[4]。也存在对这个标准定义的批评,指出其缺陷[5]。这里不对细节进行说明,我们以MySQL为例作为讨论的基础。

在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下图所示:

图1.隔离级别与read phenomena[6]


一致性

让我们回到ACID理论,重点看其中的C:一致性。在ACID中,C是实现关系数据的完整性以及业务逻辑上的一致性的本质需求。除C以外其他特性都是为了实现C而存在的,如果没有C的需求,ACID也就不存在了。

我们多谈谈一致性C。下面直接应用wikipedia关于数据库系统一致性的定义[7]。

Consistency in database systems refers to the requirement that any given database transaction must change affected data only in allowed ways. Any data written to the database must be valid according to all defined rules, including constraints, cascades, triggers, and any combination thereof. This does not guarantee correctness of the transaction in all ways the application programmer might have wanted (that is the responsibility of application-level code) but merely that any programming errors cannot result in the violation of any defined database constraints.[1]

数据库系统中的一致性强调要满足数据库系统本身的规则上的限制,它不能保障业务逻辑的正确性(以应用开发者的角度看)。即使我们将隔离级别设置为最高级别:可串行化,也不定能解决业务逻辑上的正确性要求,需要强调的是某些数据库根本就没有实现事务。SQL标准中定义的可串行化也不是我们理解的那个保障完全正确的串行化[8],而各个数据库对隔离级别的实现也是不同的[2][3][4],继而考虑到并行(concurrent)的要求,设置最高隔离级别更不现实。

再看看分布式场景,对于分布式存储系统来说,一致性变成一个和数据库系统事务一致性不同的概念[9]。从强一致性到弱一致性,各种一致性概念眼花缭乱,详细的说明可以看[9]。在分布式场景,依靠数据库端解决事务的一致性也是不可行的。


业务一致性

业务一致性是指从应用开发者角度理解的业务正确性。如前说述,数据库或者分布式存储系统可以直接帮助我们直接解决部分业务的一致性,但并不是所有,这时需要应用开发者角度实现业务一致性。分布式事务是可以解决很多业务一致性问题的,其中TCC[10]更是解决了在线商品交易的诸多需求。这里再提一个通用的模型,具体方法还是要回到数据库事务的ACID概念,我们使用一个新的概念ICS,分别叫做幂等性(idempotent)、业务一致性(Consistency)和可串行化(Serializable)。这是一个更通用的满足业务一致性要求的模型。


幂等性(idempotent)

幂等性要求业务请求可以重复提交,但是不能违反业务一致性。幂等性要求可以部分由数据库系统支持,例如设置人名,连续两次重复设置是一样的结果。而其他业务请求,例如充值,连续两次重复充值则应该和充值一次的结果一致,这一点则必须由应用开发者保证。


业务一致性(Consistency)

即业务逻辑的正确性。


可串行化(Serializable)

可串行化要求访问同样的数据由同一个角色(进程/线程/Master等)执行,且执行要严格串行化。需要说明的是串形化不能忽略Concurrency。提高concurrency可以通过以更细粒度切分数据的方式实现,具体不再赘述。


参考

[1]https://en.wikipedia.org/wiki/ACID

[2]https://docs.microsoft.com/en-us/sql/connect/jdbc/understanding-isolation-levels?view=sql-server-ver15

[3]https://www.ibm.com/support/knowledgecenter/SSAE4W_9.5.1/db2/rbafzisollevel.htm

[4]https://docs.oracle.com/database/121/CNCPT/consist.htm#CNCPT621

[5]https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf

[6]https://en.wikipedia.org/wiki/Isolation_%28database_systems%29

[7]https://en.wikipedia.org/wiki/Consistency_(database_systems)

[8]https://community.oracle.com/thread/4174436

[9]https://arxiv.org/pdf/1512.00168.pdf

  • [10]https://www.cnblogs.com/xybaby/p/7465816.html

相关推荐

甲骨文签署多项大型云协议,其一未来可贡献超300亿美元年收入

IT之家7月1日消息,根据甲骨文Oracle当地时间6月30日向美国证券交易委员会(SEC)递交的FORM8-K文件,该企业在始于2025年6月1日的202...

甲骨文获TEMU巨额合同,后者大部分基础设施将迁移至Oracle云

IT之家6月23日消息,Oracle甲骨文创始人、董事长兼首席技术官LarryEllison(拉里埃里森)在本月早些时候的2025财年第四财季和全财年财报电话会议上表示,Oracle...

Spring Boot 自定义数据源设置,这些坑你踩过吗?

你在使用SpringBoot进行后端开发的过程中,是不是也遇到过这样的问题:项目上线后,数据库连接总是不稳定,偶尔还会出现数据读取缓慢的情况,严重影响了用户体验。经过排查,发现很大一部分原因竟然...

一个开箱即用的代码生成器(一个开箱即用的代码生成器是什么)

今天给大家推荐一个好用的代码生成器,名为renren-generator,该项目附带前端页面,可以很方便的选择我们所需要生成代码的表。首先我们通过git工具克隆下来代码(地址见文末),导入idea。...

低代码建模平台-数据挖掘平台(低代码平台的实现方式)

现在来看一下数据连接。·这里是管理数据连接的空间,点击这里可以新增一个数据连接。·输入连接名称,然后输入url,是通过gdbc的方式去连接的数据库,目前是支持mysql、oracle以及国产数据库达梦...

navicat 17.2.7连接oracle数据库提示加载oracle库失败

系统:macOS15.5navicat版本:navicatpremiumlite17.2.7连接oracle测试报错:加载oracle库失败【解决办法】:放达里面找到程序,显示简介里面勾选“使...

开源“Windows”ReactOS更新:支持全屏应用

IT之家6月17日消息,ReactOS团队昨日(6月16日)在X平台发布系列推文,公布了该系统的最新进展,包括升级Explorer组件,支持全屏应用,从Wine项目引入了...

SSL 推出采用全模拟内置混音技术的模拟调音台Oracle

英国调音台传奇品牌SolidStateLogic宣布推出Oracle——一款采用全模拟内置混音技术的调音台,在紧凑的AWS尺寸机箱内集成了大型调音台的功能。该调音台提供24输入和...

47道网络工程师常见面试题,看看有没有你不会的!

你们好,我的网工朋友。网络工程师面试的时候,都会被问到什么?这个问题其实很泛,一般来说,你肯定要先看明白岗位需求写的是什么。基本上都是围绕公司需要的业务去问的。但不可否认的是,那些最基础的概念,多少也...

汉得信息:发布EBS系统安装启用JWS的高效解决方案

e公司讯,从汉得信息获悉,近日,微软官方宣布InternetExplorer桌面应用程序将于2022年6月15日正式停用。目前大部分客户都是使用IE浏览器打开EBS的Form界面,IE停用后,只能使...

36.9K star ! 推荐一个酷炫低代码开发平台!功能太强!

前言最近在逛github,看看能不能搜罗到一些对自己有帮助的开源软件。不经意间看到一个高star的java开源项目:jeecg-boot。进入在线演示版一看,感叹实在是太牛了!此开源项目不管是给来学习...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

手把手教你在嵌入式设备中使用SQLite3

摘要:数据库是用来存储和管理数据的专用软件,使得管理数据更加安全,方便和高效。数据库对数据的管理的基本单位是表(table),在嵌入式linux中有时候它也需要用到数据库,听起来好难,其实就是几个函数...

JAVA语言基础(java语言基础知识)

一、计算机的基本概念什么是计算机?计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行、自动高速处理海量数据的现代化智能电子设备。由硬件和软件组成、没有安装过任何软件的计算机称...

再见 Navicat!一款开源的 Web 数据库管理工具!

大家好,我是Java陈序员。在日常的开发工作中,常常需要与各种数据库打交道。而为了提高工作效率,常常会使用一些可视化工具进行操作数据库。今天,给大家介绍一款开源的数据库管理工具,无需下载安装软件,基...

取消回复欢迎 发表评论: