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电商平台模板(附带源码)

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

Mqtt qs 消息可靠性分析

什么是QoS 很多时候,使用MQTT协议的设备都运行在网络受限的环境下,而只依靠底层的TCP传输协议,并不能完全保证消息的可靠到达。因此,MQTT提供了QoS机制,其核心是设计了多种消息交互机制来提供不同的服务质量,来满足用户在各种场景下对消息可靠性的要求。 MQTT定义了三个Q…

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

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

动态规划--买卖股票的最佳时机的6种变形

代码随想录中对6种变形做了详细的对比和分析&#xff0c;记录如下&#xff0c;模板是固定的。 121. 买卖股票的最佳时机 class Solution { public:int maxProfit(vector<int>& prices) {vector<vector<int>> dp(prices.size(), vector<int>(2,0)…

CapCut - 剪映国际版11.1.0

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

token的理解和代码,token是什么?

面试场景&#xff1a; 以前有个学生去面试&#xff0c;公司问他&#xff0c;如果你们公司的接口文档被你的亲戚看到了&#xff0c;会怎么样&#xff1f;会导致什么问题&#xff0c;为了防止这个问题&#xff0c;需要用什么来解决&#xff1f;这个根据学生回忆的写的。 学生当…

小程序--loading和toast

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

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

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

docker (八)-dockerfile制作镜像

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

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

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

java----js常用的api

java----js常用的api 时间函数获取当前时间: DateUtil.today()时间偏移字符换时间格式化 map.computeIfAbsent添加list 时间函数 获取当前时间: DateUtil.today() String todayDateUtil.today()String today “2024-02-01”; 时间偏移 往前30天 DateTime parseDateUtil.o…

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

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

Project_Euler-06 题解

Project_Euler-06 题解 题目描述 两个公式 等差数列求和公式 i i i项&#xff1a; a i a_{i} ai​ 项数&#xff1a; n n n 公差&#xff1a; d d d 和&#xff1a; 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 与平台工程的区别

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

MySQL 的存储引擎(基本介绍)

文章目录 前言MySQL 的存储引擎介绍存储引擎是什么&#xff1f;存储引擎的特性? Innodb 与 Mylsam 的区别行级锁与表级锁是否支持事务是否支持恢复数据是否支持外键是否支持 MVCC 总结 前言 好文章不要错过&#xff0c;前两天跟大家分享的文章 1.MySQL的基础架构 2.SQL语句的…

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

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

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

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

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

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

C++基础学习

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