C++面试:事务的隔离级别和实践原理

目录

1. 读未提交(Read Uncommitted)

定义

问题

场景

实践注意事项

MySQL

SQL Server

PostgreSQL

注意

2. 读提交(Read Committed)

定义

问题

场景

如何操作

MySQL

SQL Server

PostgreSQL

注意事项

3. 可重复读(Repeatable Read)

定义

问题

场景

如何操作

MySQL

SQL Server

4. 可串行化(Serializable)

定义

问题

场景

如何操作

MySQL

SQL Server 

注意事项

实践原理

1. 读未提交(Read Uncommitted)

2. 读提交(Read Committed)

3. 可重复读(Repeatable Read)

4. 可串行化(Serializable)

总结

总结 

1. 读未提交(Read Uncommitted)

2. 读提交(Read Committed)

3. 可重复读(Repeatable Read)

4. 可串行化(Serializable)

实践原理总结


        事务的隔离级别是数据库用来定义事务在并发操作中数据可见性和隔离性的方式。SQL标准定义了四个隔离级别,每个级别都能够提供不同程度的隔离,以防止事务之间的三种读问题(脏读、不可重复读、幻读)。下面是四个隔离级别从低到高的详细解释和实践原理。

1. 读未提交(Read Uncommitted)

  • 定义:事务可以读取尚未提交的数据更改,即一个事务可以“看到”其他事务未提交的修改。
  • 问题:可能导致脏读(Dirty Read),即一个事务可能读取到另一个事务未提交的数据。
  • 场景:在需要极高性能且可以容忍脏读的情况下使用。

定义

在读未提交的隔离级别下,一个事务可以读取到其他事务未提交的数据更改。这种级别的主要特征是它不提供任何对并发事务的修改隔离。因此,事务A可以看到事务B所做的修改,即使这些修改还没有被事务B提交。这种行为使得读未提交的隔离级别提供了最低程度的隔离,从而最大化了并发访问数据库的能力。

问题

  • 脏读(Dirty Read):这是读未提交隔离级别最主要的问题。脏读发生在一个事务读取了另一个事务未提交的数据。如果后续进行的事务被回滚(Rollback),那么第一个事务读取的数据就是不正确的,因为这些数据从未被实际提交到数据库中。

场景

  • 极高性能需求:在某些需要极高性能和高吞吐量的应用中,可能会选择读未提交的隔离级别,因为它几乎不会因为锁竞争或等待而导致性能下降。这种情况下,应用可以接受数据的不一致性。
  • 可以容忍脏读:如果应用逻辑可以容忍脏读,或者应用场景中脏读带来的问题不会对业务结果造成重大影响,那么可以考虑使用读未提交的隔离级别。例如,对于一些实时性要求高但数据准确性要求不是非常严格的监控系统,可能会使用读未提交。

实践注意事项

  • 当选择读未提交级别时,开发者必须意识到其带来的风险,尤其是脏读可能导致的数据不一致性问题。
  • 应用程序的逻辑需要能够处理或忽略因脏读导致的潜在错误或数据不一致。
  • 在实现时,开发者应当考虑到读未提交隔离级别可能对事务的完整性和一致性带来的影响,并评估是否适合业务需求。

MySQL

        在MySQL中,你可以通过以下SQL语句设置会话级别的隔离级别为读未提交:

        总的来说,读未提交的隔离级别在提供最大并发性的同时牺牲了数据的准确性和一致性。因此,它只适用于那些能够接受这种权衡的特定场景。

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

        或者,设置全局级别的隔离级别(影响新创建的连接):

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SQL Server

        在SQL Server中,你可以使用以下命令设置事务隔离级别为读未提交:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

        在执行此命令后,当前会话中的所有事务都将运行在读未提交的隔离级别下,直到隔离级别被更改。 

PostgreSQL

        PostgreSQL默认不支持设置为读未提交级别,因为其最低级别是读提交(Read Committed)。不过,可以通过设置事务为只读来模拟避免锁的行为:

BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED READ ONLY;

注意

  • 在使用上述命令之前,请确保你已经理解了所选隔离级别对数据一致性和系统性能的影响。
  • 设置事务隔离级别应该根据具体的应用场景和数据一致性需求谨慎进行。
  • 不同的数据库管理系统可能有不同的默认隔离级别,以及对隔离级别支持的不同,务必查阅你所使用的数据库系统的官方文档以获取准确信息。

 

2. 读提交(Read Committed)

  • 定义:事务只能读取已经提交的数据更改。这意味着一个事务在执行过程中看到的数据是一致的,在事务开始时“快照”了数据。
  • 问题:防止了脏读,但是可能会发生不可重复读(Nonrepeatable Read),即在同一个事务内两次读取同一数据集合时可能会看到不同数据。
  • 场景:适用于大多数应用,是许多数据库系统的默认隔离级别。

        读提交(Read Committed)是数据库事务隔离的一个常用级别,它确保了一个事务只能读取到其他事务已经提交的数据更改。这个隔离级别解决了脏读问题,但可能会导致不可重复读。

定义

        在读提交隔离级别下,一个事务在执行过程中只能看到其他事务已经提交的更改。这意味着,如果一个事务在执行期间,另一个事务提交了对某些数据的修改,那么这些修改在第一个事务的后续操作中就会变得可见。这种级别通常通过在读操作开始时获取数据的“快照”来实现,确保读操作的一致性。

问题

  • 不可重复读(Nonrepeatable Read):这是读提交隔离级别的主要问题。不可重复读发生在一个事务内,当它尝试两次读取同一数据集合时,由于其他事务的提交,可能会看到不同的数据。

场景

  • 广泛应用:读提交是许多数据库系统的默认隔离级别,因为它在数据一致性和系统性能之间提供了较好的平衡。它适用于大多数应用场景,尤其是那些对性能有要求但同时需要避免脏读的场合。

如何操作

        具体设置事务隔离级别的SQL语句取决于你使用的数据库系统。

MySQL

        在MySQL中,可以使用以下命令为当前会话设置隔离级别:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

        或者,为全局设置隔离级别(影响新的会话): 

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SQL Server

        在SQL Server中,设置事务隔离级别为读提交:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
PostgreSQL

        PostgreSQL默认使用读提交作为其事务的隔离级别。如果需要明确设置,可以使用:

 

BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;

注意事项

  • 在多数数据库系统中,读提交是默认的隔离级别,但了解如何显式设置它仍然很重要,特别是在需要确保应用在特定隔离级别下运行时。
  • 明确设置事务的隔离级别可以帮助避免应用中潜在的数据一致性问题。
  • 使用读提交隔离级别时,开发者需要意识到不可重复读的可能性,并在必要时通过应用逻辑来处理这种情况。

 

3. 可重复读(Repeatable Read)

  • 定义:保证在同一个事务中多次读取同一数据的结果是一致的。
  • 问题:虽然解决了不可重复读的问题,但可能会遇到幻读(Phantom Read),即一个事务读取了几行数据,另一个并发事务插入了一些行,当第一个事务再次读取时会“看到”额外的“幻影”行。
  • 场景:适用于需要锁定行以防止不可重复读,但可以接受幻读的情况。

        可重复读(Repeatable Read)是一种事务隔离级别,旨在确保在同一个事务中多次读取同一数据集合的结果保持一致,即使在这个事务执行期间其他事务进行了提交操作。

定义

        在可重复读隔离级别下,一旦事务开始,它对同一数据集合的多次读取将会看到同样的数据,无论其他事务是否已经提交了对这些数据的更改。这主要通过锁定读取的数据行来实现,防止其他事务进行修改。

问题

  • 幻读(Phantom Read):尽管可重复读隔离级别能够防止不可重复读,但它可能遇到幻读问题。幻读发生在当一个事务读取了几行数据后,另一个并发事务插入了一些新的行,当第一个事务再次读取同一数据集时,它会看到之前未见过的新行。

场景

  • 行锁定需求:适用于需要锁定行以防止不可重复读的应用场景,但这些场景可以容忍幻读的问题。它是一种比读提交更严格的隔离级别,适用于对数据一致性要求较高的情况。

如何操作

        以下是在一些流行的数据库管理系统中设置可重复读隔离级别的方法:

MySQL

        MySQL的默认事务隔离级别就是可重复读。如果需要显式设置,可以使用:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

        或者,设置全局级别:

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SQL Server

        在SQL Server中,可以通过以下命令设置事务隔离级别为可重复读:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

4. 可串行化(Serializable)

  • 定义:最高的隔离级别,通过强制事务串行执行,避免了脏读、不可重复读和幻读问题。
  • 问题:性能开销最大,因为它会锁定事务涉及的数据行。
  • 场景:适用于需要完全避免并发问题的场合,如银行金融系统。

        可串行化(Serializable)是数据库事务隔离级别中最高的级别,它通过强制事务以串行的方式执行,从而避免了脏读、不可重复读和幻读等所有并发问题。

定义

        在可串行化隔离级别下,每个事务都是在独立的环境中执行,好像系统中在同一时间只执行这一个事务一样。这通过锁定事务访问的数据行,或者使用乐观并发控制机制来实现,从而确保事务的执行结果与如果事务被依次串行执行的结果相同。

问题

  • 性能开销:可串行化隔离级别提供了最高程度的数据一致性保障,但同时也带来了最大的性能开销。这是因为它需要锁定事务访问的数据行,或者采取其他机制来保证事务的串行执行,这会显著减少并发性能。
  • 锁竞争:在高并发环境下,可串行化隔离级别可能导致大量的锁竞争,增加了死锁的风险。

场景

  • 高一致性需求:适用于需要完全避免并发问题,对数据一致性要求极高的场景,如银行金融系统、交易系统等,这些系统不能容忍任何并发引起的数据不一致性问题。

如何操作

        下面是在一些流行的数据库管理系统中设置可串行化隔离级别的方法:

MySQL
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

 或者,设置全局级别:

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SQL Server 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

注意事项

  • 使用可串行化隔离级别时,开发者需要特别注意性能和锁竞争问题,确保系统的并发需求和性能目标不会因为高隔离级别而受到影响。
  • 在一些情况下,可能需要通过调整应用逻辑或数据库设计来减少对可串行化隔离级别的依赖,以改善系统的整体性能和并发能力。
  • 由于不同的数据库管理系统可能有不同的实现细节,开发者在设置事务隔离级别时应当参考特定数据库系统的官方文档,以确保正确地应用这些设置。

        通过正确地应用可串行化隔离级别,可以在需要时为应用程序提供最高水平的数据一致性保护,但同时也需要仔细管理和调优以避免性能瓶颈。

 

实践原理

        在实践中,数据库通过使用锁机制(如行锁、表锁)、多版本并发控制(MVCC)等技术来实现这些隔离级别:

  • 读未提交:不使用锁,允许读取未提交的数据。
  • 读提交:通常使用锁机制或MVCC来实现,确保只读取到已提交的数据。
  • 可重复读:在读提交的基础上增加锁定或MVCC策略,以确保同一事务中的多次读取结果一致。
  • 可串行化:通过对参与事务的所有数据行加锁或使用序列化操作来防止并发执行。

        数据库实现事务隔离级别的实践原理主要依赖于锁机制和多版本并发控制(MVCC)。这两种技术可以确保数据的一致性和隔离性,同时允许数据库系统在维护这些保证的同时,最大化并发操作。下面详细介绍这些技术是如何应用于不同的事务隔离级别的。

1. 读未提交(Read Uncommitted)

  • 实践原理:在读未提交的隔离级别下,事务可以读取其他事务未提交的数据。这种级别不使用数据行锁定来防止其他事务读取未提交的数据,因此允许脏读发生。这是因为系统的设计目标是最大化查询的并发性,牺牲数据的一致性。

2. 读提交(Read Committed)

  • 锁机制:在读提交级别,数据库使用锁机制(如行锁)或MVCC来保证一个事务只能读到其他事务已经提交的数据。在使用锁的系统中,当一个事务正在修改数据时,会对这些数据加锁,直到事务提交,从而防止其他事务读取这些未提交的数据。
  • MVCC:在使用MVCC的数据库系统中,每次写操作都会创建数据的一个新版本(或快照),而读操作可以访问到事务开始前的最新提交版本,从而保证了在当前事务中只能看到已提交的更改。

3. 可重复读(Repeatable Read)

  • 锁机制:为了实现可重复读,数据库在读提交的基础上进一步增加了锁定策略。这通常意味着在事务开始时锁定读取的所有数据行,直到事务结束。这阻止了其他事务对这些行进行修改,保证了事务内的读取结果一致性。
  • MVCC:在MVCC系统中,事务会看到在它开始时或之前已经提交的数据的一个稳定视图(snapshot)。这意味着即使其他事务在这期间提交了新的更改,这些更改也不会反映在当前事务的查询结果中,从而避免了不可重复读。

4. 可串行化(Serializable)

  • 锁机制:在最高的隔离级别可串行化中,数据库通过锁定事务涉及的所有数据行来实现。这种级别通常要求事务在执行读取或修改之前对相关数据行加锁,并持有这些锁直到事务结束。这样做虽然可以防止脏读、不可重复读和幻读,但会大大减少并发性能,增加死锁的可能性。
  • 序列化操作:另一种实现可串行化隔离级别的方法是使用序列化操作,它通过一种算法来确定事务的执行顺序,确保事务的执行结果与按某一序列顺序串行执行这些事务的结果相同。这种方法在不同的数据库系统中实现不同,有些系统可能通过MVCC加上特定的锁策略或其他机制来实现。

总结

        数据库在实现事务隔离级别时需要在数据一致性、系统性能和并发性之间做出平衡。锁机制提供了直接的数据保护,但可能影响并发性;而MVCC通过允许并发的读和写操作,提供了更高的并发性,但实现相对复杂。不同的数据库系统可能会选择不同的策略来实现这些隔离级别,具体取决于系统的设计目标和工作负载的特点。

总结 

数据库事务隔离级别是数据库管理系统(DBMS)中用于控制事务程序之间并发访问数据时可能发生的问题的一组定义。这些隔离级别提供了不同程度的隔离,以防止事务之间的干扰,如脏读、不可重复读和幻读等问题。以下是四种标准的SQL事务隔离级别的总结,包括它们的定义、问题、适用场景以及数据库实现这些隔离级别的实践原理。

1. 读未提交(Read Uncommitted)

  • 定义:允许事务读取其他事务未提交的数据,是隔离级别中最低的级别。
  • 问题:可能导致脏读。
  • 场景:适用于对一致性要求不高,追求极高性能的场景。
  • 实践原理:不使用锁,允许最大程度的并发,但牺牲数据一致性。

2. 读提交(Read Committed)

  • 定义:事务只能读取已经提交的数据更改,是许多数据库系统的默认隔离级别。
  • 问题:可能发生不可重复读。
  • 场景:适用于大多数应用,平衡了一致性和性能。
  • 实践原理:使用锁机制或MVCC,确保只读取到已提交的数据。

3. 可重复读(Repeatable Read)

  • 定义:保证在同一个事务中多次读取同一数据的结果是一致的。
  • 问题:可能遇到幻读。
  • 场景:适用于需要锁定行以防止不可重复读的情况。
  • 实践原理:增加锁定或MVCC策略,以确保事务中的多次读取结果一致。

4. 可串行化(Serializable)

  • 定义:最高的隔离级别,通过强制事务串行执行,避免了所有并发问题。
  • 问题:性能开销最大,因为它会锁定事务涉及的数据行。
  • 场景:适用于需要完全避免并发问题的场合,如银行金融系统。
  • 实践原理:通过对参与事务的所有数据行加锁或使用序列化操作来防止并发执行。

实践原理总结

        数据库通过使用锁机制(如行锁、表锁)和多版本并发控制(MVCC)等技术来实现这些隔离级别。读未提交不使用锁,允许最大程度的并发;读提交使用锁机制或MVCC来确保只读取到已提交的数据;可重复读在读提交的基础上增加锁定或MVCC策略,以确保事务中的多次读取结果一致;可串行化通过对参与事务的所有数据行加锁或使用序列化操作来防止并发执行,提供了最高水平的数据一致性保护,但同时也需要仔细管理和调优以避免性能瓶颈。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】网络配置network详解

一,network的概述 解决痛点(能干什么?): (1)容器间的互联和通信以及端口映射 (2)容器IP变动时候,可以通过服务名直接网络通信而不受到影响 二,n…

webrtc mediasoup sctp 起什么作用? 用来传输什么数据

WebRTC是一种用于实时通信的开放标准,而mediasoup是一个基于WebRTC的流媒体服务器。SCTP(Stream Control Transmission Protocol)是WebRTC中的一个传输协议,它在WebRTC中起到了重要的作用。 SCTP主要用于在WebRTC中传输数据通道&…

功率信号的频谱

目录 1. 前言2. 功率信号的频谱3. 参考资料 1. 前言 知识点1:函数周期性判定定理   假设函数 f ( x ) f(x) f(x) 和函数 g ( x ) g(x) g(x) 均为周期性函数,其最小正周期分别为 T f T_f Tf​ 和 T g T_g Tg​,若 T f / T g T_f/T_g T…

搜索引擎评价指标及指标间的关系

目录 二分类模型的评价指标准确率(Accuracy,ACC)精确率(Precision,P)——预测为正的样本召回率(Recall,R)——正样本注意事项 P和R的关系——成反比F值F1值F值和F1值的关系 ROC(Receiver Operating Characteristic)——衡量分类器性能的工具AUC&#xff…

2月2日作业 C语言笔试题整理

1、请简述gcc的编译步骤 预处理:展开头文件、删除注释、替换宏 编译:检查语法正确性,生成汇编文件 汇编:把汇编语言转换为二进制文件,生成目标文件 链接:把多个目标文件链接为可执行文件 2、C语言中基…

基于Java SSM框架实现校园兼职系统项目【项目源码+论文说明】

基于java的SSM框架实现校园兼职系统演示 摘要 社会的发展和科学技术的进步,互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱,也逐渐进入了每个学生的使用。互联网具有便利性,速度快,效率高,…

买电脑注意事项之CPU型号后面的字母都代表什么意思

在 CPU 型号后面的字母通常表示该 CPU 的一些特性或用途。不同的字母可能代表不同的系列、性能级别、功耗特性等。以下是一些常见的 CPU 后缀字母及其可能的含义: U(例如:i5-8250U): Ultra Low Power:表示低功耗&#…

Elasticsearch(简称ES)性能优化 实践

Elasticsearch(简称ES)性能优化主要包括以下几个方面: 索引优化: 选择合适的分片数:根据业务需求和数据量合理设置分片数,避免过多或过少分片造成性能问题。分片数过多会导致创建分片速度变慢、集群易崩溃…

[office] excel计算客户名单的人数 COUNTA 函数:“销售额”不仅是金额的总和 #知识分享#职场发展#知识分享

excel计算客户名单的人数 COUNTA 函数:“销售额”不仅是金额的总和 前文中介绍的 SUM 函数,是在日常工作中使用频率最高的函数之一。但是,在实际操作时也会出现问题。比如在计算销售额总和时,SUM 函数得出的结果为金额总和。但是…

RISC-V指令格式

RISC-V指令格式 1 RISC-V指令集命名规范2 RISC-V指令集组成2.1 基础整数指令集2.2 扩展指令集 3 RISC-V指令格式3.1 指令表述3.2 指令格式 本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 RISC-V指令集命名规范 前面提到过RV32I,这是…

本地部署 SalesGPT

本地部署 SalesGPT 0. 背景1. SalesGPT 项目介绍2. SalesGPT 项目 Github 地址3. 本地部署 SalesGPT4. 运行 SalesGPT 0. 背景 最近有同事想玩玩 SalesGPT,结果发现使用 OpenAI API 时,会发生超过 Limit 的问题无法继续对话。 今天尝试通过本地部署开源…

5. 基础网络服务与应用配置

5.1 实验一:FTP 基础配置实验 5.1.1 实验介绍 5.1.1.1 关于本实验 设备支持多种文件管理方式,用户根据任务和安全性要求选择合适的文件管理方式。 用户可以通过直接登录系统、FTP(File Transfer Protocol)、TFTP(T…

从编程中理解:大脑的短期记忆和长期记忆

在编程中,我们可以将大脑的短期记忆和长期记忆类比为程序中的变量作用域和持久化存储。在Unity C#编程环境下,可以这样解释: 假设金庸武侠世界中的人物张无忌正在修炼九阳真经。我们用C#代码来模拟他学习武功的过程,其中涉及的“短期记忆”与“长期记忆”。 public class…

第8章 SpringBoot任务管理

学习目标 熟悉SpringBoot整合异步任务的实现 熟悉SpringBoot整合定时任务的实现 熟悉SpringBoot整合邮件任务的实现 开发web应用时,多数应用都具备任务调度功能。常见的任务包括异步任务,定时任务和发邮件任务。我们以数据库报表为例看看任务调度如何帮助改善系统设计。报表可…

【深度学习】数据归一化/标准化 Normalization/Standardization

目录 一、实际问题 二、归一化 Normalization 三、归一化的类型 1. Min-max normalization (Rescaling) 2. Mean normalization 3.Z-score normalization (Standardization) 4.非线性归一化 4-1 对数归一化 4-2 反正切函数归一化 4-3 小数定标标准化(Demi…

Day17、18、19学习记录

#c语言知识 内存管理 1.作用域 (1)代码块作用域(代码块是{}之间的一段代码) (2)函数作用域 (3)文件作用域 2.局部变量(自动变量auto): 在函…

jmeter-03界面介绍

文章目录 主界面介绍测试计划介绍线程组介绍线程组——选择测试计划,右键-->添加-->线程-->线程组 主界面介绍 测试计划介绍 测试计划:本次测试所需要的所有内容,即父线程 线程组介绍 jmeter讲究一个概念:一个线程一…

Linux内存管理:(十一)页面分配之慢速路径

文章说明: Linux内核版本:5.0 架构:ARM64 参考资料及图片来源:《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址: zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 水位管理和分配优先级 页面分配…

小白水平理解面试经典题目_二维数组类LeetCode 2966 Divide Array【排序算法实现】

2966 将数组划分为具有最大差值的数组 小白渣翻译: 给定一个大小为 n 的整数数组 nums 和一个正整数 k 。 将数组分成一个或多个大小为 3 的数组,满足以下条件: nums 的每个元素都应该位于一个数组中。一个数组中任意两个元素之间的差异小…

力扣每日一题 ---- 1906. 查询差绝对值的最小值

本题中,我们的题目求的是差值的最小值,我们考虑一个因素,当前题目中给出的数组是没有排序过的,那么想要求的差值,是不是要两两配对进行判断差值最小值。这里我们就很费时间了, O(N^2)的时间复杂度&#xf…