MySQL篇—事务和隔离级别介绍

☘️博主介绍☘️

✨又是一天没白过,我是奈斯,DBA一名✨

✌️擅长Oracle、MySQL、SQLserver、Linux,也在积极的扩展IT方向的其他知识面✌️

❣️❣️❣️大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注❣️❣️❣️

    今天,作为新一年的第一篇文章,与大家分享关于MySQL事务和隔离级别的知识。在数据库管理系统中,事务是确保数据完整性和一致性的关键机制。通过事务,我们可以将多个数据库操作组合成一个逻辑单元,要么全部执行,要么全部不执行,从而确保数据的正确性和一致性。

    而隔离级别则是控制多个事务并发执行时如何相互影响的关键因素。不同的隔离级别提供了不同的数据可见性和并发性能,需要根据具体的业务需求和性能要求来选择合适的隔离级别。

    一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性、持久性)属性。

原子性(Atomicity)事务开始后所有操作,要么全部做完,要么全部不做不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没收到。

隔离性(Jsolation)同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

持久性(Durability)事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。小结:原子性是事务隔离的基础,隔离性和持久性是手段,最终目的是为了保持数据的一致性

总结:原子性是事务隔离的基础,隔离性和持久性是手段,最终目的是为了保持数据的一致性。


          

目录

案例:设置4种隔离级别,分析对mysql的影响。建议设置为read-committed事务级别

级别一:读未提交read-uncommitted:一个事务可以读到另一个事务未提交的结果为脏数据

级别二:读已提交read-committed:只有在事务提交后,其结果才会被其他事务看见

级别三:可重复读repeatable-read:无论事务对数据是否进行操作,事务是否提交,对于同一份数据的读取结果总是相同的。只有退出会话(事务)才能同步数据

级别四:串行化serializable:,隔离级别最高,牺牲了系统的并发性。就是锁表(不是行锁),事务修改表时并没有提交,禁止其他所有事务连接当前表


          

通过现象反映隔离级别效果:

01更新丢失(lost update):当系统允许两个事务同时更新同一数据是,发生更新丢失。例:事务A将数值改为1并提交,事务B将数值改为2并提交。这时值变为2。不算问题,正常情况

02脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。

03不可重复读(non-repeatable read):同一查询语句在同一事务中多次进行,如果这个过程中其他事务提交了所做的修改或删除,会发生每次返回不同的结果集,此时发生非重复读,那么就是意味着同一事务执行完全相同的select语句时可能看到不一样的结果。导致这种情况的原因可能有:

             (1)有一个交叉的事务有新的commit,导致了数据的改变

             (2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit多个commit提交时,只读一次出现结果不一致

04幻读(phantom read):出现幻读的情况是由于并发事务引起的。在同一个事务内对于相同的查询条件,在两次查询之间新增或删除了符合条件的数据,导致第二次查询结果与第一次查询结果不一致的情况。解决幻读的办法:

            (1)调整事务隔离级别为串行化

            (2)通过间隙锁和next-key locks,而间隙锁和next-key locks只有在隔离级别为可重复读或以上才有(二八定律,RR级别: 20%的事务存在幻读;80%的事务不存在幻读的风险)。在可重复读级别下查询加上for update后如果有数据返回就是行锁,没有数据就加上间隙锁和next-lock key锁住一个范围不允许其他事务DML只能自己才能DML。

例:事务A改了未提交,事务B改其他,A再查。  A把所有‘100’改为‘200’,B把所有‘50’改为‘100’。A查询100,发现还有数据,产生幻读。 RR 级别下存在幻读的可能,但也是可以使用对记录手动加 X锁(RR模式下的X锁会同时进行间隙锁和next-key locks来防止幻读) 的方法消除幻读。SERIALIZABLE 正是对所有事务都加 X锁 才杜绝了 幻读

           

四种隔离级别(MySQL默认Repeated Read,建议改为read committed):

(1)read uncommitted:最低的隔离级别,一个事务可以读到另一个事务未提交的结果为脏数据。

(2)read committed (DEFAULT):只有在事务提交后,其更新结果才会被其他事务看见,解决了更新丢失、脏读。Oracle、db2、sql server默认的隔离级别

(3)Repeated Read(重复读):MySQL默认隔离级别。在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交,它确保同一事务的多个实例在并发读取数据时,看到同样的数据行,只有退出会话(同事务)才能同步数据。解决了更新丢失、脏读、不可重复读。RR 级别下存在幻读的可能,解决幻读的办法:

             (1)调整事务隔离级别为串行化

             (2)通过间隙锁和next-key locks,而间隙锁和next-key locks只有在隔离级别为可重复读或以上才有(二八定律,RR级别: 20%的事务存在幻读;80%的事务不存在幻读的风险)。在可重复读级别下查询加上for update后如果有数据返回就是行锁,没有数据就加上间隙锁和next-lock key锁住一个范围不允许其他事务DML只能自己才能DML

(4)Serializable(串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。就是X锁表(不是行锁),一个事务修改表时并没有提交,禁止其他所有事务连接当前表。SERIALIZABLE 正是对所有事务都加 X锁 才杜绝了 幻读,但很多场景下我们的业务 sql 并不会存在 幻读 的风险。SERIALIZABLE 的一刀切虽然事务绝对安全,但性能会有很多不必要的损失。故可以在 RR 下根据业务需求决定是否加锁,存在幻读风险我们加锁,不存在就不加锁,事务安全与性能兼备,这也是 RR 作为 mysql默认隔是个事务离级别的原因,所以需要正确的理解 幻读。

                   

read committedRepeated Read在处理并发事务时区别

1)"Read Committed" 隔离级别:

每个读操作只能看到已经提交的事务所做的更改,而不能看到其他未提交的事务所做的更改。

事务在读取数据时会对每一行数据加共享锁,直到读操作完成才会释放锁定。

2)"Repeatable Read" 隔离级别:

在事务开始后,所有的查询都只能看到在该事务开始之前已经提交的数据,不会看到其他事务所做的更改。

事务在读取数据时会对整个表加共享锁,直到事务结束才会释放锁定。

总结:

      "Read Committed" 隔离级别只保证读取已提交的数据,可以避免脏读,但可能出现不可重复读和幻读。

     "Repeatable Read" 隔离级别通过在事务期间锁定读取的数据,可以避免不可重复读,但仍可能出现幻读。

      根据具体的业务需求和并发环境来选择合适的隔离级别,如果需要更高的数据一致性和读取的稳定性,可以选择 "Repeatable Read" 隔离级别。如果对一致性要求相对较低,需要更好的并发性能,可以选择 "Read Committed" 隔离级别。

                      

隔离级别相关参数:

mysql> show variables like '%tx_isolation%';     ---默认REPEATABLE-READ对数据不安全。建议修改为READ-COMMITTED

                   

设置隔离级别:

mysql> set global tx isolation='READ-COMMITTED|READ-UNCOMMITTED|REPEATABLE-READ|SERIALIZABLE';
注:在会话和全局级别修改参数,都不会永久修改参数。永久修改参数只能将参数添加到my.cnf文件,然后重启生效。添加参数:transaction-isolation=READ-COMMITTED

                     

案例:设置4种隔离级别,分析对mysql的影响。建议设置为read-committed事务级别

级别一:读未提交read-uncommitted:一个事务可以读到另一个事务未提交的结果为脏数据

mysql> set global tx_isolation='READ-UNCOMMITTED';     ---影响所有会话,但重启失效

mysql> show variables like '%tx_isolation%';  

mysql> set global autocommit=0;       ---关闭自动提交功能。这里只是为了测试,所以关闭了自动提交功能,默认开启

           

会话一:

mysql> create table tb(id int,name varchar(20));
mysql> insert into tb values (1,'itpux1');
mysql> select * from tb;

          

会话二:

mysql> select * from tb;         ---其他会话查到未提交事务的数据

                   

级别二:读已提交read-committed:只有在事务提交后,其结果才会被其他事务看见

mysql> set global tx_isolation='READ-COMMITTED';    ---影响所有会话,但重启失效

mysql> show variables like '%tx_isolation%';  

mysql> set global autocommit=0;       ---关闭自动提交功能。这里只是为了测试,所以关闭了自动提交功能,默认开启

          

会话一:

mysql> create table tb(id int,name varchar(20));
mysql> insert into tb values (1,'itpux1');
mysql> select * from tb;

         

会话二:

mysql> select * from tb; 

        

会话一:

mysql> commit;

         

会话二:

mysql> select * from tb;         ----事务提交后,其他事务才能读取数据

                     

级别三:可重复读repeatable-read:无论事务对数据是否进行操作,事务是否提交,对于同一份数据的读取结果总是相同的。只有退出会话(事务)才能同步数据

mysql> set global tx_isolation='REPEATABLE-READ';    ---影响所有会话,但重启失效

mysql> show variables like '%tx_isolation%';  

mysql> set global autocommit=0;       ---关闭自动提交功能。这里只是为了测试,所以关闭了自动提交功能,默认开启

           

会话一:

mysql> select * from tb;

mysql> update tbset id=1000 where name='itpux1';
mysql> commit;

              

会话二(会话一打开时确保会话二一同打开):

mysql> select * from itpux; 

[root@mysql2 ~]# mysql -u root -p    ---退出会话,相当于结束一个事务。然后重新登录一个会话(同事务)
mysql> select * from tb;        ---查询到其他事务提交的事务

            

级别四:串行化serializable:隔离级别最高,牺牲了系统的并发性。就是锁表(不是行锁),事务修改表时并没有提交,禁止其他所有事务连接当前表

mysql> set global tx_isolation='SERIALIZABLE';    ---影响所有会话,但重启失效

mysql> show variables like '%tx_isolation%';  

mysql> set global autocommit=0;       ---关闭自动提交功能。这里只是为了测试,所以关闭了自动提交功能,默认开启

         

会话一:

mysql> select * from tb;

mysql> update itpux set id=9999 where name='itpux1';

          

会话二:

mysql> select * from tb;          ----查询没有响应。事务级别为串行化,事务没结束之前,对操作的对象进行锁表

           

会话一:

mysql> commit;          ---结束事务(提交事务)

          

会话二:

mysql> select * from tb;   ---事务完成后,其他事务才能读取数据

总结:串行化serializable事务隔离级别,只有读读之间可以并发;读写/写读/写写都要阻塞进行锁表。也就是no MVCC(多版本并发控制)

            

    好啦今天的内容结束了,希望这边文章可以让大家对事务和隔离级别有所了解。

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

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

相关文章

SG-8201CJA(汽车可编程晶体振荡器)

爱普生的SG-8021CJA是一款符合AEC-Q100标准的晶体振荡器,专为要求苛刻的汽车/ADAS应用(如激光雷达和相机ECU)而设计。它采用爱普生的内部低噪声小数NPLL,输出 频率高达170MHz,相位抖动小于1/25,稳定性比之前…

【前端素材】推荐实用的后台管理系统ebazer电商平台模板(附带源码)

一、需求分析 后台管理系统网站是指用于管理和控制网站、应用程序或系统后台运行的管理工具。它通常是网站或应用程序的管理者、管理员或内容编辑人员使用的界面,具有一系列功能来管理用户、内容、数据和系统设置。以下是后台管理系统网站的功能和特点:…

Open Systems Interconnection(开放式系统互联)

OSI(Open Systems Interconnection,开放式系统互联)模型是一个描述计算机网络体系结构和通信系统的参考模型,它将计算机网络分成七个抽象的层级,每个层级负责不同的功能,从物理连接到最终的应用程序。以下是…

CapCut - 剪映国际版11.1.0

​【应用名称】:CapCut - 剪映国际版 【适用平台】:#Android 【软件标签】:#CapCut #剪映国际版 【应用版本】:11.1.0 【应用大小】:231MB 【软件说明】:软件升级更新。目前大家广泛使用的最令人惊叹、最专…

小程序--loading和toast

一、loading wx.showLoading({})显示loading提示框。wx.hideLoading({})隐藏loading提示框。 title:文字提示内容 mask:是否显示透明蒙层,防止触摸穿透。 更多属性参考showLoading官方文档。 wx.showLoading({title: 加载中...,mask: true }…

力扣面试150 验证回文串 双指针 Character API

Problem: 125. 验证回文串 文章目录 思路复杂度Code 思路 👨‍🏫 参考题解 Character.isLetterorDigit(char c):判读字符 c 是否是字母或者数字 Character.toLowerCase(char c):将字符 c 转换为小写字母 复杂度 时间复杂度: …

docker (八)-dockerfile制作镜像

一 dockerfile dockerfile通常包含以下几个常用命令: FROM ubuntu:18.04 WORKDIR /app COPY . . RUN make . CMD python app.py EXPOSE 80 FROM 打包使用的基础镜像WORKDIR 相当于cd命令,进入工作目录COPY 将宿主机的文件复制到容器内RUN 打包时执…

十、计算机视觉-腐蚀操作

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、什么是腐蚀二、如何实现腐蚀三、腐蚀的原理 一、什么是腐蚀 在我们生活中常会见到腐蚀,比如金属表面受到氧化或其他化学物质的侵蚀,导致…

观察者模式和发布订阅模式的区别

从下图中可以看出,观察者模式中观察者和目标直接进行交互,而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但…

Project_Euler-06 题解

Project_Euler-06 题解 题目描述 两个公式 等差数列求和公式 i i i项: a i a_{i} ai​ 项数: n n n 公差: d d d 和: S n S_{n} Sn​ a n a 1 ( n − 1 ) d S n n ( a 1 a n ) 2 a_{n} a_{1} (n - 1)d\\ S_{n} \frac{n(a_…

深究 DevOps 与平台工程的区别

今天,我们将讨论平台工程和 DevOps 的关系。尽管这两个概念有一些共同点,但它们仍然是截然不同的,我们将具体了解它们之间的区别。本文旨在解释当代软件工程中的这两个基本概念。通过实际案例,我们将分别说明这两个方法如何塑造了…

leetcode刷题电话号码的字母组合(人工智能解答版本)

题目描述 解题思路 一开始想用暴力破解的方法来进行解题,就是循环。但是想到随着数字的增多,循环行不通。想到最近使用的一个人工智能助手,于是我把题目发送给了它,直接给出了递归的解决方法。递归分为两个条件,一个就…

【k近邻】 K-Nearest Neighbors算法原理及流程

【k近邻】 K-Nearest Neighbors算法原理及流程 【k近邻】 K-Nearest Neighbors算法距离度量选择与数据维度归一化 k近邻算法(K-Nearest Neighbors,简称KNN)是一种常用的监督学习算法,可以用于分类和回归问题。在OpenCV中&#xff…

【关于python变量类型学习笔记】

python的变量类型 在创建变量时会在内存中开辟一个空间,变量是存储在内存中的值。 根据变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。 变量可以指定不同的数据类型,这些变量可以存储整数,…

C++基础学习

string char转string vector转string 截取字符串 字符串反转 string转int 正则匹配

Nginx 反向代理配置

Nginx就不废话了,web服务器。 最近在备案一个域名,想要备案,部署一个服务器,平常很少自己配置Nginx,今天记录下。 1、反向代理 正向代理 指 客户端通过代理访问后端服务 反向代理 指 服务器推出一个客户&#xff0…

环信IM Android端实现华为推送详细步骤

首先我们要参照华为的官网去完成 ,以下两个配置都是华为文档为我们提供的 1.https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/android-config-agc-0000001050170137#section19884105518498 2.https://developer.huawei.com/consumer/cn/doc/HMSCore…

#gStore-weekly | gMaster功能详解之数据库管理

gMaster提供了数据库管理功能。该功能可以对集群中的数据库进行集中管理,可以查看各个数据库详细信息。能够方便的对数据库进行新建、构建、导出、备份、还原、删除操作。 登录gMaster,点击左侧菜单【数据库】下的【数据库管理】,进入数据库…

【开源】JAVA+Vue.js实现高校学生管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 学院课程模块2.3 学生选课模块2.4 成绩管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学院课程表3.2.3 学生选课表3.2.4 学生成绩表 四、系统展示五、核心代码5.1 查询课程5.2 新…

动态获取 微信小程序appid / 自定义启动命令

官网:https://uniapp.dcloud.net.cn/collocation/package.html#%E7%94%A8%E6%B3%95 小程序开发完成之后需要一套代码多个小程序使用,每次都需要在manifest.json文件中手动修改,大大增加了开发的复杂度。 官网:https://uniapp.dcl…