数据库的事务四大特性(ACID)、详解隔离性以及隔离级别、锁

文章目录

  • 🎉数据库的事务四大特性(ACID)以及隔离性
    • 一、事务的四大特性✨
      • 1、原子性(Atomicity)🎊
      • 2、一致性(Consistency)🎊
      • 3、隔离性(Isolation)🎊
      • 4、持久性(Durability)🎊
    • 二、详解事务的隔离性✨
      • 1、脏读🔮
      • 2、不可重复读🔮
      • 3、虚读(幻读)🔮
      • 4、隔离级别🔮
        • 1️⃣ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
        • 2️⃣ Read committed (读已提交):可避免脏读的发生。
        • 3️⃣ Repeatable read (可重复读):可避免脏读、不可重复读的发生。*MySQL默认隔离级别
        • 4️⃣ Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
    • 三、怎样算是一个事务🪄
      • 1、从第一次执行SQL语句开始到执行commit或者rollback结束。中间不管执行多少SQL语句都是同一个事务内。
      • 2、事务的开始与结束
      • 3、数据库如何实现事务的
    • 四、常用操作🌈-----记住:设置数据库的隔离级别一定要是在开启事务之前!
      • 1、查看提交状态命令
      • 2、关闭自动提交
      • 3、查看隔离级别
      • 4、修改隔离级别
      • 5、开启事务-----只要执行一条SQL语句就是开启事务,不一定非要使用start transaction;
      • 6、结束事务
    • 五、数据库事务怎么做✨
      • 1、如何进行事务🏆
        • 1️⃣ 建立引擎支持InnoDB,InnoDB支持数据库事务操作
        • 2️⃣ 设置autocommit为false
        • 3️⃣ 修改隔离级别
        • 4️⃣ 开启事务
        • 5️⃣ 执行SQL语句
        • 6️⃣ commit或者rollback(回滚)
      • 2、对Read Uncommitted级别进行操作
        • 1️⃣ 脏读:两次数据
      • 3、对Read Committed级别进行操作
        • 2️⃣ 不可重复读-----此时避免了脏读,但是还存在不可重复读的问题,看此标题下第二张图
      • 4、repeatable read隔离级别
        • 3️⃣ 解决了脏读、不可重复读
    • 六、锁🔒
      • 1、代码层次的乐观锁、删除锁
      • 2、数据库层次的悲观锁:

🎉数据库的事务四大特性(ACID)以及隔离性

一、事务的四大特性✨

1、原子性(Atomicity)🎊

  原子性是指事务包含的所有操作要么全部成功,要么全部回滚失败。因此事务的的操作如果成功就必须完全应用到数据库,如果操作失败不能对数据库有任何影响。

2、一致性(Consistency)🎊

  一致性是指事务必须是数据库从一个一致状态变换到另一个一致状态,也就是说一个事务执行之前和执行之后必须处于一致状态。

  🪄例如:那转账来说,假设用户A和用户B两者的钱加起来是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱加起来应该还得是5000,这就是事务的一致性。

3、隔离性(Isolation)🎊

  隔离性是指当多个用户并发访问数据库时,比如操作同一张表时,数据库为每个用户开启的事务,不能被其他事务的操作干扰,多个并发事务要互相隔离。

  即要达到一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后开始,这样每个事务都感觉不到有其他的事务在并发执行。

  关于事务的隔离性又提供了多种隔离级别,如读已提交、读未提交、可重复读、串行化,稍后会讲到。

4、持久性(Durability)🎊

  持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变是永久的,即便是在数据库系统中遇到 故障的情况下也不会丢失提交事务的操作。

  例如我们在使用JSDC操作数据库时,在提交事务后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务已经正确提交,即使数据库出现了问题,也必须要将我们的事务完全执行完成,否则会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

二、详解事务的隔离性✨

  以上介绍完事务的四大特性(简称ACID),现在重点来说明一下事务的隔离性,当多个线程都开启事务的操作数据库中的数据,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生哪些问题:

1、脏读🔮

  脏读是指在一个事务处理过程里读取了另一个未提交事务中的数据。

  当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

update account set money=money+100 where name=’B’;  (此时A通知B)update account set money=money - 100 where name=’A’;

  当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

2、不可重复读🔮

不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

3、虚读(幻读)🔮

幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

4、隔离级别🔮

现在来看看MySQL数据库为我们提供的四种隔离级别(从低到高排序):

1️⃣ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

  第一隔离级别怕回滚,因为它能读取到别的事务未提交的数据。如果当前事务将这个数据当成真正的数据,那么如果别的事务回滚,那么就会数据错误,导致脏读。

2️⃣ Read committed (读已提交):可避免脏读的发生。

第二个隔离级别怕提交,因为提交会导致不可重复读。

3️⃣ Repeatable read (可重复读):可避免脏读、不可重复读的发生。*MySQL默认隔离级别
4️⃣ Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

三、怎样算是一个事务🪄

1、从第一次执行SQL语句开始到执行commit或者rollback结束。中间不管执行多少SQL语句都是同一个事务内。

2、事务的开始与结束

start transaction; # 开启事务
commit;或者rollback; # 事务结束

3、数据库如何实现事务的

  服务端有日志记录功能,新操作是记录到日志中的,commit会将日志中的记录刷到硬盘中,rollback就是将日志中的记录删除掉了

四、常用操作🌈-----记住:设置数据库的隔离级别一定要是在开启事务之前!

1、查看提交状态命令

show variables like '%auto%';

2、关闭自动提交

set autocommit = 0;

3、查看隔离级别

select @@transaction_isolation; # 8.x版本数据库系统
show variables like 'transaction_isolation'; # 8.x版本数据库系统
SELECT @@tx_isolatione 5.x

4、修改隔离级别

set session transaction isolation level ; # 8.x
set session transaction isolation ; # 5.x

5、开启事务-----只要执行一条SQL语句就是开启事务,不一定非要使用start transaction;

start transaction;

6、结束事务

commit;或者
rollback;

五、数据库事务怎么做✨

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

1、如何进行事务🏆

1️⃣ 建立引擎支持InnoDB,InnoDB支持数据库事务操作
2️⃣ 设置autocommit为false
show variables like '%auto%'; # 展示事务提交信息
set autocommit=0; # 设置autocommit为false
set autocommit=1; # 设置autocommit为true
3️⃣ 修改隔离级别
select @@transaction_isolation; # 查看隔离级别
set session transaction isolation level read uncommitted; # 设置隔离级别,此时设置为读未提交
4️⃣ 开启事务
5️⃣ 执行SQL语句
select * from employee;
update employee set sal=100 where empno=1022;
6️⃣ commit或者rollback(回滚)
commit;
rollback;

2、对Read Uncommitted级别进行操作

1️⃣ 脏读:两次数据

在这里插入图片描述

3、对Read Committed级别进行操作

2️⃣ 不可重复读-----此时避免了脏读,但是还存在不可重复读的问题,看此标题下第二张图

在这里插入图片描述

在这里插入图片描述

因为两个事务对同一个数据进行操作违反了隔离性,死锁。

在这里插入图片描述

对不同数据操作不报错

在这里插入图片描述

4、repeatable read隔离级别

3️⃣ 解决了脏读、不可重复读

在这里插入图片描述

记住:设置数据库的隔离级别一定要是在开启事务之前!

如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connection对象的setAutoCommit(false)方法之前。调用Connection对象的setTransactionIsolation(level)即可设置当前链接的隔离级别,至于参数level,可以使用Connection对象的字段:

在这里插入图片描述

在JDBC中设置隔离级别的部分代码:

在这里插入图片描述

后记:隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

六、锁🔒

1、代码层次的乐观锁、删除锁

在代码层次,乐观锁是一种在数据读取时不加锁的并发控制机制。它假设多个事务在同一时间对同一数据进行操作的可能性较小,因此只在更新数据时进行版本检查,以防止数据被其他事务同时修改。在MySQL中,可以使用版本号或时间戳等机制来实现乐观锁。例如,在更新数据时,可以检查该数据的版本号是否与最初读取时一致,如果不一致,则表示有其他事务修改了该数据,此时可以选择回滚或重试等操作。

2、数据库层次的悲观锁:

在数据库层次,悲观锁是一种在数据读取时加锁的并发控制机制。它假设多个事务在同一时间对同一数据进行操作的可能性较大,因此每次读取数据时都会对相应的数据进行加锁,以防止其他事务同时修改该数据。
在MySQL中,可以使用SELECT … FOR UPDATESELECT … LOCK IN SHARE MODE等语句来实现悲观锁。
例如,使用SELECT … FOR UPDATE语句时,会对选定的行进行加锁,直到事务结束时才释放锁。在此期间,其他事务无法对该行进行修改。

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

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

相关文章

蓝桥杯刷题

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析(3) 👉🏻最大降雨量 原题链接&#xff1…

MySQL的基本建表及操作

MySQL的基本建表及操作 文章目录 MySQL的基本建表及操作一、表的结构二、建库和建表1.建库2.建表 三、复制表四、查表和删表 一、表的结构 数据库表的结构由表名、列名、列数据类型、列约束和索引等元素组成。具体来说,下面是数据库表的结构元素的详细解释&#xf…

汽车标定技术(一):XCP概述

目录 1.汽车标定概述 2.XCP协议由来及版本介绍 3.XCP技术通览 3.1 XCP上下机通信模型 3.2 XCP指令集 3.2.1 XCP帧结构定义 3.2.2 标准指令集 3.2.3 标定指令集 3.2.4 页切换指令集 3.2.5 数据采集指令集 3.2.6 刷写指令集 3.3 ECU描述文件(A2L)概述 3.3.1 标定上位…

vuepress使用及拓展(骚操作)

官网 文章目录 背景问题思考方案思索实现方案实现结果存在问题 背景 当前开放平台文件静态保存在前端项目,每次修改都需要通过修改文件发版的方式,很不便利。 1、需要前端手动维护 2、每次小的修改都要发版 随着对接业务的增多,对接文档的变…

学习笔记|多组率卡方检验和Fisher确切法|个案加权|规范表达|《小白爱上SPSS》课程:SPSS第十六讲 | 多组率卡方检验和Fisher确切法

目录 学习目的软件版本原始文档多组率卡方检验和Fisher确切法一、实战案例二、统计策略三、SPSS操作1、个案加权2、卡方检验 四、结果解读第一,分组统计描述结果第二,卡方检验。 五、规范报告1、规范表格2、规范文字 六、划重点 学习目的 SPSS第十六讲 …

Java 谈谈你对OOM的认识

文章目录 前言一、基础架构二、常见OOM1、栈内存溢出java.lang.StackOverflowError2、堆内存溢出java.lang.OutOfMemoryError:Java heap space3、GC回收时间过长java.lang.OutOfMemoryError: GC overhead limit exceeded4、NIO程序堆外内存溢出java.lang.OutOfMemor…

golang 发起 http 请求,获取访问域名的 ip 地址(net, httptrace)

前言 今天碰到了个需求,我要知道程序对外访问的 http 请求域名的 ip 地址。 直接查看 golang 的 net/http 包,发现 Response 中并没有我想要的 ip 信息。 考虑到在 OSI 七层模型中,ip 是网络层协议,而 http 是应用层协议。去翻…

【Qt之事件过滤器】使用

介绍 事件过滤器是Qt中一种重要的机制,用于拦截并处理窗口和其他对象的事件。 它可以在不修改已有代码的情况下,动态地增加、删除一些处理事件的代码,并能够对特定对象的事件进行拦截和处理。 在Qt中,事件处理经过以下几个阶段&…

3D医学三维技术影像PACS系统源码

一、系统概述 3D医学影像PACS系统,它集影像存储服务器、影像诊断工作站及RIS报告系统于一身,主要有图像处理模块、影像数据管理模块、RIS报告模块、光盘存档模块、DICOM通讯模块、胶片打印输出等模块组成, 具有完善的影像数据库管理功能,强大…

SpringBoot框架使用AOP + 自定义注解实现请求日志记录

一、SpringBoot记录日志 文章目录 一、SpringBoot记录日志1.1、环境搭建1.2、配置FastJson1.3、自定义LogRecord注解1.4、定义日志实体类1.5、创建HttpRequestUtil工具类1.6、定义AOP切面1.7、编写测试类1.8、运行测试 1.1、环境搭建 搭建SpringBoot工程。引入【spring-boot-st…

基于动力学模型的机械臂滑膜控制

一、滑模控制设计思路 参考资料:https://zhuanlan.zhihu.com/p/463230163(思路理解) https://blog.csdn.net/xiaohejiaoyiya/article/details/90271529(干扰的处理) 滑模控制的思路有两个关键,一个是设计…

【广州华锐互动】风景区规划VR虚拟现实教学系统

风景区规划VR虚拟现实教学系统是一种新兴的教学工具,它可以通过虚拟现实技术,为学生提供一种沉浸式的、实时的、全方位的景区规划体验。 在风景区规划VR虚拟现实教学系统中,学生可以通过虚拟现实技术,实时地与景区进行交互。他们可…