首页 > 数据库 >数据库系统 第22节 事务隔离级别案例分析

数据库系统 第22节 事务隔离级别案例分析

时间:2024-08-24 18:54:45浏览次数:8  
标签:事务 隔离 22 余额 提交 数据库系统 级别 读取

1. 读未提交 (Read Uncommitted)

场景:假设有两个事务,事务A正在更新账户余额,事务B正在读取账户余额。

  • 事务A(未提交):开始更新账户余额,将余额从$1000减少到$900。
  • 事务B(读取):读取账户余额,看到余额为$900(事务A未提交的更改)。

问题:如果事务A最终回滚,事务B读取到的$900将是无效的,这就是脏读。

2. 读已提交 (Read Committed)

场景:继续上述的账户余额例子,但数据库设置为读已提交隔离级别。

  • 事务A(提交):更新账户余额,将余额从$1000减少到$900,并提交更改。
  • 事务B(读取):在事务A提交后读取账户余额,正确地看到余额为$900。

问题:虽然避免了脏读,但如果事务B在事务A提交之前和之后都读取余额,可能会遇到不可重复读的问题。

3. 可重复读 (Repeatable Read)

场景:数据库设置为可重复读隔离级别,事务B需要确保在整个事务过程中读取到相同的数据。

  • 事务B(开始):读取账户余额,看到余额为$1000。
  • 事务A(更新并提交):在事务B进行中,更新账户余额为$900并提交。
  • 事务B(再次读取):在同一事务中再次读取账户余额,仍然看到余额为$1000。

问题:在这个隔离级别下,事务B避免了不可重复读的问题,但可能会遇到幻读,即如果事务A在事务B进行中插入了新的记录,事务B在再次执行查询时可能会看到这些新记录。

4. 序列化 (Serializable)

场景:数据库设置为序列化隔离级别,事务将顺序执行。

  • 事务A(锁定并更新):开始更新账户余额,数据库锁定相关数据,将余额从$1000减少到$900。
  • 事务B(等待):尝试读取账户余额,但由于事务A持有锁,事务B必须等待。
  • 事务A(提交):更新完成并提交,释放锁。
  • 事务B(读取):现在可以读取账户余额,看到更新后的余额为$900。

问题:序列化隔离级别避免了脏读、不可重复读和幻读,但可能导致性能问题,因为事务必须等待其他事务释放锁。

通过这些例子,我们可以看到每个隔离级别如何处理并发事务,以及它们如何影响数据的一致性和事务的并发性能。开发者需要根据具体的应用场景和需求来选择最合适的隔离级别。

例子 1:脏读(Read Uncommitted)

场景:银行账户转账

  • 事务1(转账操作):Alice想要向Bob转账$100。事务开始时,她账户里有$1000。
  • 事务2(读取操作):同时,事务2读取Alice的账户余额,由于隔离级别是读未提交,它读取到了$1000,尽管这个值还没有提交。
  • 事务1(回滚):如果事务1因为某种原因被回滚,Alice的账户实际上应该是$1000,但事务2已经基于错误的信息进行了操作。

结果:脏读发生,事务2基于未提交的数据做出了决策。

例子 2:不可重复读(Read Committed)

场景:在线库存销售

  • 事务1(库存更新):一个在线商店的库存系统开始更新库存数量,将某商品的库存从100件减少到90件。
  • 事务2(销售操作):一个顾客查看商品库存,看到有90件库存(读已提交级别,只能读取已提交的数据)。
  • 事务1(提交):库存系统完成更新并提交事务。
  • 事务2(再次检查):顾客决定购买时再次检查库存,发现库存现在是100件,因为事务1已经提交。

结果:顾客遇到了不可重复读的问题,因为两次读取的结果不一致。

例子 3:可重复读(Repeatable Read)

场景:图书馆书籍借阅

  • 事务1(借书检查):一个读者想要借阅一本书,他检查发现这本书在图书馆有三本副本。
  • 事务2(借书操作):同时,另一个读者借阅了其中一本,事务提交。
  • 事务1(再次检查):第一个读者决定借书,再次检查副本数量,由于隔离级别是可重复读,他仍然看到有三本副本。

结果:第一个读者避免了不可重复读的问题,因为他在整个事务过程中看到的是一致的快照。

例子 4:幻读(Repeatable Read)

场景:工资等级更新

  • 事务1(读取操作):HR部门开始更新工资等级,他们查询所有工资等级低于$50,000的员工。
  • 事务2(更新操作):同时,另一个HR员工为一些员工增加工资,将他们的工资等级提高到$50,000以上,并提交事务。
  • 事务1(再次查询):第一个HR员工再次查询工资等级低于$50,000的员工,发现一些之前查询到的员工的工资等级已经提高,尽管他们的查询条件没有变化。

结果:发生了幻读,因为事务1在两次查询之间看到了不同的结果,尽管他们的查询条件是相同的。

例子 5:序列化(Serializable)

场景:在线投票系统

  • 事务1(投票操作):用户A对候选人X投票,事务开始,数据库锁定了候选人X的投票计数。
  • 事务2(投票操作):同时,用户B尝试对候选人X投票,但由于序列化隔离级别,事务2必须等待事务1完成。
  • 事务1(提交):用户A的投票被记录并提交。
  • 事务2(执行):用户B现在可以对候选人X投票,他的票被记录。

结果:序列化隔离级别确保了投票操作的顺序执行,避免了并发问题,但可能导致性能问题,因为事务必须等待。

这些例子展示了在不同的事务隔离级别下,数据库如何处理并发事务,以及这些级别如何影响数据的一致性和完整性。在设计数据库事务时,开发者需要仔细考虑这些因素,以确保应用程序的正确性和性能。

例子 6:死锁(Serializable)

场景:在线购物车

  • 事务1(添加商品):用户A将商品A添加到购物车,事务锁定了商品A的库存。
  • 事务2(添加商品):同时,用户B将商品B添加到购物车,事务锁定了商品B的库存。
  • 事务1(尝试更新):用户A接着尝试添加商品B到购物车,但由于用户B已经锁定了商品B,事务1必须等待。
  • 事务2(尝试更新):用户B接着尝试添加商品A到购物车,但由于用户A已经锁定了商品A,事务2必须等待。

结果:发生了死锁,因为两个事务都在等待对方释放锁,没有事务能够继续执行。

例子 7:不可重复读与可重复读(Read Committed vs. Repeatable Read)

场景:会议室预订系统

  • 事务1(预订会议室):员工A检查会议室1在下周一是否可用,发现是空的。

  • 事务2(预订会议室):同时,员工B预订了会议室1,并提交了事务。

  • 事务1(再次检查):员工A决定预订会议室1,但由于隔离级别是读已提交,他发现会议室1已经被预订。

  • 隔离级别变更:如果系统使用可重复读隔离级别,员工A在决定预订时将始终看到会议室1是空的,因为在他的事务开始时会议室1的状态已经被锁定。

结果:在可重复读隔离级别下,员工A避免了不可重复读的问题,因为他的事务在整个过程中看到的是一致的状态。

例子 8:幻读与序列化(Repeatable Read vs. Serializable)

场景:工资系统更新

  • 事务1(查询工资等级):HR部门查询所有工资低于$50,000的员工,准备进行工资调整。

  • 事务2(更新工资):同时,另一个HR员工更新了部分员工的工资至$50,000以上,并提交了事务。

  • 事务1(再次查询):HR部门再次查询工资低于$50,000的员工,发现一些员工的工资已经提高,即使他们的查询条件没有变化。

  • 隔离级别变更:如果系统使用序列化隔离级别,事务1和事务2将不会并发执行,而是会顺序执行。HR部门在查询和更新工资时,不会看到其他事务的更改,直到它们提交。

结果:在序列化隔离级别下,HR部门避免了幻读的问题,因为事务是顺序执行的,每次查询都是基于当前的提交状态。

例子 9:性能影响(Read Committed vs. Serializable)

场景:高并发的股票交易平台

  • 隔离级别:如果使用读已提交隔离级别,平台可以允许多个用户同时读取股票价格,但可能会遇到不可重复读的问题。
  • 性能问题:如果使用序列化隔离级别,虽然可以避免并发问题,但可能会导致性能瓶颈,因为每个事务都必须等待前一个事务完成。

结果:在高并发系统中,选择合适的隔离级别是一个平衡性能和数据一致性的决策。

通过这些例子,我们可以看到事务隔离级别对于处理并发事务和维护数据一致性的重要性。开发者需要根据具体的业务需求和性能考虑来选择最合适的隔离级别,并在必要时通过应用程序逻辑来进一步控制并发行为。

标签:事务,隔离,22,余额,提交,数据库系统,级别,读取
From: https://blog.csdn.net/hummhumm/article/details/141438563

相关文章

  • 全新Versal HBM 系列自适应 SoC:XCVH1542-1MSEVSVA3697、XCVH1542-2MLELSVA4737、XCVH1
    系列概述VersalHBM系列具有快速内存、安全连接和自适应计算的异构集成,可消除内存绑定的计算密集型工作负载(如机器学习、数据库加速、下一代防火墙和高级网络测试仪)的处理和内存瓶颈。它从底层开始构建,以适应不断发展的算法、协议和数据速率。与VersalPremium系列*相比,通过集......
  • 代码随想录第15天,110.平衡二叉树,257. 二叉树的所有路径, 404.左叶子之和, 222.完全二叉
    110.平衡二叉树//平衡二叉树,理解稍微有点难度#include<iostream>#include<algorithm>//Forstd::absandstd::maxfunctionsstructTreeNode{intval;TreeNode*left;TreeNode*right;TreeNode(intx):val(x),left(nullptr),right(nullptr......
  • SQL Server 2019及Solidworks 2022安装错误解决
    问题关键词:SQLServer2019;Solidworks2022;WaitontheDatabaseEnginerecoveryhandlefailed.TLDR:Windows11系统扇区过大导致SQLServer无法处理。参考这一个StackOverflow问题中的相关回答。问题解决(SQLServer2019安装问题):以管理员身份运行CommandPrompt或者......
  • MySQL 四种隔离级别
    事务的四个特征(ACID)事务具有四个特征:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性简称为ACID特性。1、原子性。事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做2、一致性。事务执行的结果必须是使数据......
  • 解决方案 | VS2022 社区版 获取工具和功能找不到visual stdio安装程序的终极解决办法
      首先这是一种解决方法:https://blog.csdn.net/Wysnbb/article/details/124588395 其次,如果上面方法解决不了,那么可以重新下载vs社区版。(不要误会,并不是下载10G+的东西)https://visualstudio.microsoft.com/zh-hans/vs/community/  下载得到:  安装VisualStud......
  • 【C语言初级课程详解】第22课时-C语言结构体
    C 结构体C数组允许定义可存储相同类型数据项的变量,结构是C编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。结构体中的数据成员可以是基本数据类型(如int、float、char等),也可以是其他结构体类型、指针类型等。结构用于表示一条记录,假设您想要跟......
  • 枚举 day22
    枚举类型是Java中一种用于统一管理有限的常量数据的数据类型。它将常量设置为对象,提高了代码的可读性和简洁性。通过使用枚举类型,可以在代码中更方便地读取和使用常量。packagecom.shujia.day22;/*1.创建枚举类的属性(成员变量),必须是作为私有常量出现2.必须......
  • 调度器22—调频-interactive governor分析
    基于msm-4.4一、概述InteractiveGovernor‌实现调频的核心思想是通过选择最小的频率来满足目标负载。这个过程涉及两个主要因素:系统频率的平均频率loadadjfreq和系统设定好的目标负载targetload。InteractiveGovernor通过choose_freq()函数来选择频率,目的是使选频后的......
  • cas:2247545-20-4|Biotin-LC-PEG4-NHS ester|生物素-LC-四聚乙二醇-琥珀酰亚胺酯
    描述Biotin-LC-PEG4-NHSester中的NHS-PEG4-Biotin是一种聚乙二醇化水溶性试剂,用于对抗体、蛋白质和其他含伯胺的大分子进行简单有效的生物素标记。N-羟基琥珀酰亚胺酯(NHS)基团与赖氨酸和N-末端氨基特异性且有效地反应形成稳定的酰胺键。亲水性聚乙二醇(PEG)间隔臂赋予......
  • ACL 2022 SWCC 论文拆解
    引言本文贡献Wearemotivatedtoaddresstheaboveissueswiththegoalofmakingbetteruseofcooccurrenceinformationofevents.Tothisend,wepresentSWCC:aSimultaneousWeaklysupervisedContrastivelearningandClusteringframeworkforeventreprese......