【MYSQL】事务的4大属性,对隔离级别的详细讲解

news2024/11/16 17:47:11

目录

1.原子性和持久性

1.1.手动提交事务

1.2.自动提交事务

 1.3.事务的原理:

2.隔离性

1.读未提交(Read Uncommitted)

 2.读提交(Read Committed)

3.可重复读

4.串行化

3.一致性

4.理解读提交和可重复读的实现原理区别

4.1.模拟 MVCC

4.2.read view

4.3.RR 与 RC的本质区别


事务的4大属性:原子性,持久性,隔离性,一致性;

在mysql中只有innodb支持事务,myisam是不支持事务的;

事务的作用:

  1. 由于事务的隔离性,多个用户同时访问数据库时不必担心相互之间的影响,提高并发性和数据安全性;
  2. 事务的提交和回滚操作还可以保证数据的安全性和完整性;

1.原子性和持久性

1.1.手动提交事务

1.事务的基本操作 

  1. 使用begin或者start transaction,创建事务
  2. 中间可以增删改操作
  3. 使用commit提交事故 

2.创建保存点和回滚操作

  • savepoint  标记;
  • rollback to  标记:回滚到标记位置;rollback回滚到事务开头(begin位置)

只要事务未提交(未commit)就可以使用回滚操作 

1.2.自动提交事务

查看自动提交事务状态:
    show variables like 'autocommit';
设置为关闭:
    SET AUTOCOMMIT=0; 
设置为开启:
    SET AUTOCOMMIT=1; 

由下图可以得出:

  1. 自动提交事务是对输入单条sql语句(不使用手动提交的情况)做自动提交;
  2. 如果关闭自动提交,那么单条sql不会被写入磁盘,保证原子性; 

 1.3.事务的原理:

原子性:要么做完,要么不做,没有中间态 ;可以分为3个状态,执行前,执行中,执行后;

1.事务的3个状态可以为

  • 执行前:使用begin从磁盘中把数据拿到内核缓冲区,再从内核缓冲区拷贝到用户层的buffer pool中,简单的说就是把磁盘数据保存到内存的用户层的缓冲区;
  • 执行中:使用sql语句对拿到内存中数据进行增删改;
  • 执行后:使用commit把修改的内存数据,拿到磁盘去;

如何保证的原子性:如果不使用commit交付数据,事务结束后就自动会回滚到执行前,使用commit交付数据那么就是执行后

持久性是什么:就是已经交付的数据(commit),就会保存在磁盘中且不受回滚的约束

2.隔离性

  • MySQL服务可能会同时被多个客户端进程(线程)访问访问的方式以事务方式进行(并发执行)
  • 数据库中,为了保证事务并发执行过程中尽量不受干扰,就有了一个重要特征:隔离性
  • 在不同的场景需要不同的隔离级别:有4种,读未提交、读提交、可重复读、串行化

查看设置隔离级别:

select @@global.tx_isolation;查看全局隔离级别

select @@session.tx_isolation;查看会话隔离级别

设置隔离等级格式:set session/global transaction isolation level read uncommitted/read committed/repeatable read/serializable; //全局和会话选一个,隔离等级4选1;

设置会话隔离等级

1.读未提交(Read Uncommitted)

在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题;(脏读,幻读,不可重复读);

脏读:一个事务进行增删改,另一个正在执行的事务可以读取到未提交(commit)的数据; 

脏读的问题举例:要对查询到表的多条记录发奖励,另外一个事务新增了一行记录且没有提交,那么奖励多发一个; 

 2.读提交(Read Committed)

该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变,不可重复读的问题

不可重复读:多个事务并发执行,一个事务增/删/改一条数据且提交,其他的正在执行的事务就可以看到这条数据;

不可重复的问题举例:我们按分数发奖励,100分发100块钱,90分发50块钱,80分发30块,小明得了100分,在比较100分的时候给他发100块,在比较90分的时候入过另一个事务把小明改为90分并且提交,那么小明又可以得到50块,那么就出问题了

 

3.可重复读

概念:这是MySQL默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是一般数据库会有幻读问题,mysql没有这个问题被解决了

幻读:这一系列隔离都是加锁完成的,但是新增的数据没到磁盘一般锁不能限制,所以其他事务插入,查询时会看到新增数据,mysql是使用Next-Key锁(GAP+行锁)解决的;

 

4.串行化

 概念:: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了 幻读的问题。它在每个读的数据行上面加上共享锁。但是可能会导致超时和锁竞争(这种隔离级别太极端, 实际生产基本不使用)

3.一致性

例如转账问题A有1000¥,B有800¥,A给B转账200¥,A有800¥B拥有1000¥;

一致性的概念:事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。A有1000B有800是一个一致性状态,A有800B有1000是另一个一致性状态;

如何保证转账成功呢,防止A转账了,B没有收到了,

  1. 有回滚和提交这种方法(原子性),保护已经修改的数据不会回滚(持久性),并发执行不受影响(隔离性);
  2. 用户对A和B的数据修改

由上可得:一致性并没有具体的实例,是由用户和mysql的特性来共同来维护的概念

4.理解读提交和可重复读的实现原理区别

数据库并发的场景有三种:

  • 读读:不存在任何问题,也不需要并发控制;
  • 读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
  • 写写:有线程安全问题,可能会存在更新丢失问题

读写

多版本并发控制( MVCC )是一种用来解决 读-写冲突 的无锁并发控制

4个记录隐藏列字段:

  • DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记录/最后一次修改该记录的事务ID,识别不同事务身份;
  • DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一 般在 undo log 中)
  • DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键)如果数据表没有主键, InnoDB 会自动以 DB_ROW_ID 产生一 个聚簇索引
  • 删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了,flag=0未删,flag=1已删除(内存)

加上隐藏列: 

undo日志

  • 是一个内存缓冲区,用来保存日志数据;

4.1.模拟 MVCC

修改张三这行记录的过程

  • 事务10,因为要修改,所以要先给该记录加行锁。
  • 修改前,现将改行记录拷贝到undo log中,所以,undo log中就有了一行副本数据。(原理就是写时拷贝)
  • 所以现在 MySQL 中有两行同样的记录。现在修改原始记录中的name,改成 '李四'。并且修改原始记录的隐藏字段 DB_TRX_ID 为当前 事务10 的ID, 我们默认从 10 开始,之后递增。而原始记录的回滚指针 DB_ROLL_PTR 列, 里面写入undo log中副本数据的地址,从而指向副本记录,既表示我的上一个版本就是它
  • 事务10提交,释放锁。

现在有一个事务11,要对当前记录的age修改为38;

 这样,我们就有了一个基于链表记录的历史版本链。所谓的回滚,无非就是用历史数据,覆盖当前数据

  • 上面的一个个版本,我们可以称之为一个个的快照。
  1. 当前读:读取最新的记录,就是当前读。增删改,都叫做当前读,select也有可能当前读,比如:select lock in share mode(共享锁), select for update
  2. 快照读:读取历史版本(一般而言),就叫做快照读。

4.2.read view

read view是一个类(mysql1使用c++实现),下面是它的一部分;

class ReadView {
// 省略...
private:

/** 高水位,大于等于这个ID的事务均不可见*/
trx_id_t m_low_limit_id

/** 低水位:小于这个ID的事务均可见 */
trx_id_t m_up_limit_id;

/** 创建该 Read View 的事务ID*/
trx_id_t m_creator_trx_id;

/** 创建视图时的活跃事务id列表*/
ids_t m_ids;
//省略...
};
  1. 无论是读提交还是可重复读都遵守下面的概念;它们两的区别不在这里,所以不要想着它们的概念来理解下面的图,反而更难理解
  2. 由read view来决定可不可读,形成快照后分为3部分,第一部分都可读,第二部分提交的就可读,第三部分都不可读;
  • 第一部分:creator_limit_id==DB_TRX_ID就是自己的事务id当然可读,DB_TRX_ID<up_limit_id说明不在这个m_ids(活跃事务id列表)范围之内,而且因为事务id自增长的,比最小活跃事务还小说明它以前已经提交的;
  • 第二部分:up_limit_id到low_limit_id之间;不就是m_ids里面的活跃事务吗;那么已经提交的可读,未提交不可读(这里不是不可重复读问题,读提交和可重复读都支持read view来决定可不可读概念,下面说明它们的区别是读提交每次快照读就会生成一个新的read view,可重复读快照读生成一个read view就不会再生成了);
  • 第三部分:DB_DRX_ID>=low_limit_id,比m_ids的所以活跃事务都大,那么是不可读的;

4.3.RR 与 RC的本质区别

可重复读隔离等级下

 

  •  用例1与用例2:唯一区别仅仅是 表1 的事务B在事务A修改age前 快照读 过一次age数据
  • 而表2的事务B在事务A修改age前没有进行过快照读。

RR 与 RC的本质区别:

  • 正是Read View生成时机的不同,从而造成RC,RR级别下快照读的结果的不同
  • 在RR级别下的某个事务的对某条记录的第一次快照读会创建一个快照及Read View, 将当前系统活跃的其他事务记录起来(m_ids)
  • RR级别此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用(活跃事务)过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改(第三部分)不可见;
  • 而在RC级别下的,事务中,每次快照读都会新生成一个快照和Read View, 这就是我们在RC级别下的事务中可以 看到别的事务提交的更新的原因
  • 在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务 中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。
  • 正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。

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

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

相关文章

iptables

目录 iptables概述 netfilter/iptables 关系&#xff1a; 四表五链 四表&#xff1a; 五链&#xff1a; 数据包到达防火墙时&#xff0c;规则表之间的优先顺序&#xff1a; 规则链之间的匹配顺序&#xff1a; 主机型防火墙&#xff1a; 网络型防火墙&#xff1a; ipta…

Uart,RS232,RS485串口通讯协议学习

目录 定义 UART&#xff08;通常被称为串口,简单意味着使用广泛&#xff0c;具有普适性) RS232 RS232电平转换 RS485 -Recommended Standard (再推荐标准) 485和232的对比 RS485组网 总结 定义 串口是我们都很熟悉的&#xff0c;尤其是需要串口调试的时候,打印信息插…

C语言函数大全-- _w 开头的函数(4)

C语言函数大全 本篇介绍C语言函数大全-- _w 开头的函数 1. _wstrtime 1.1 函数说明 函数声明函数功能wchar_t *_wstrtime(wchar_t *buffer);用于获取当前系统时间并返回一个宽字符字符串表示&#xff0c;格式为 "HH:MM:SS"&#xff08;小时:分钟:秒&#xff09; …

2023 Vue开发者的React入门

Vue 和 React 都是流行的 JavaScript 框架&#xff0c;它们在组件化、数据绑定等方面有很多相似之处 本文默认已有现代前端开发(Vue)背景&#xff0c;关于 组件化、前端路由、状态管理 概念不会过多介绍 0基础建议详细阅读 Thinking in React-官方文档 了解 React 的设计哲学 R…

彻底理解粘性定位 - position: sticky(IT枫斗者)

彻底理解粘性定位 - position: sticky 介绍 粘性定位可以被认为是相对定位(position: relative)和固定定位(position: fixed)的混合。元素在跨越特定阈值前为相对定位&#xff0c;之后为固定定位。例如: .sticky-header { position: sticky; top: 10px; }在 视口滚动到元素…

【JavaWeb】--05.Request和Response、JSP、会话技术

文章目录 Request和Response1.概述2.Request对象2.1 Request继承体系2.2Request获取请求数据2.3 IDEA创建Servlet2.4 请求参数中文乱码问题POST请求解决方案GET请求解决方案 2.5 Request请求转发 3.Response对象3.1 Response设置响应数据功能介绍3.2 Response请求重定向3.3 路径…

【全网首测】5G随身Wi-Fi —— 中兴U50 Pro

说到随身Wi-Fi&#xff0c;大家应该都不陌生。 它是一个专门将移动信号转换成Wi-Fi信号的设备&#xff0c;经常被用于旅行和出差场景&#xff0c;也被人们亲切地称为“上网宝”。 现在&#xff0c;我们已经全面进入了5G时代&#xff0c;随身Wi-Fi也升级迭代&#xff0c;出现了支…

人工智能的界面革命,消费者与企业互动的方式即将发生变化。

本文来源于 digitalnative.substack.com/p/ais-interface-revolution 描述了一种社会现象&#xff1a; 随着真实友谊的减少和虚拟友谊的增加&#xff0c;越来越多的人开始将AI聊天机器人视为自己的朋友&#xff0c;甚至建立了深厚的情感纽带。这可能与当前人们越来越孤独的现实…

面向“伙伴+华为”体系,华为产品力的变与不变

在日前举办的“华为中国合作伙伴大会2023”上&#xff0c;华为面向政企市场提出了建设“伙伴华为”体系的发展方向。可想而知&#xff0c;接下来会有更多伙伴加入这一体系&#xff0c;也会有更多客户可以借由这个体系加速完成自身的数字化转型和智能化升级。而产品与技术&#…

luaplus Windows编译(一)

前言 LuaPlus是Lua的C增强&#xff0c;也就是说&#xff0c;LuaPlus本身就是在Lua的源码上进行增强得来的。用它与C进行合作&#xff0c;是比较好的一个选择。 1:准备 luaplus_all 下载地址&#xff1a;https://github.com/jjensen/luaplus51-all jamplus 下载地址 https://gi…

基于神经网络算法的鱼类迁徙轨迹拟合研究

本试验采用HTI Model 291便携型声学标签接收系统,包括的基本部件有:291便携型声学标签接收器1台,590型水听器4根,最新795型声学标签40枚,490-LP 型标签编程器1台,690系列电缆400m,492微型声学标签探测器1台,115VAC型滤波器1台,TagProgrammer 、MarkTags和AcousticTag专…

30个数据科学工作中最常用的 Python 包

Python 可以说是最容易入门的编程语言&#xff0c;在numpy&#xff0c;scipy等基础包的帮助下&#xff0c;对于数据的处理和机器学习来说Python可以说是目前最好的语言。 在各位大佬和热心贡献者的帮助下Python拥有一个庞大的社区支持技术发展&#xff0c;开发两个各种 Python…

Oracle中数据导出成HTML的操作实践

spool是Oracle中将数据到成文件常用的一种工具&#xff0c;但它的强大&#xff0c;不仅仅是数据的导出&#xff0c;在格式和内容上&#xff0c;还可以自定义&#xff0c;甚至生成像AWR一样的统计报告。 参考《SQL*Plus Users Guide and Reference》中第7章"Generating HTM…

光纤仿真相关求解——光纤芯层和包层电磁场分布求解

要求解光纤中的电磁场分布&#xff0c;就要构建合适的物理模型 将光纤假设为圆柱状的波导&#xff0c;求解满足均匀原型介质波导边界条件的麦克斯韦方程组&#xff0c;即可 z分量的亥姆霍兹方程为&#xff1a; 对应在圆柱坐标系下为&#xff1a; 用分离变量法求解Ez&#xff…

如果你不想工作了,先做这3件事

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 英国作家毛姆有句名言&#xff1a;“我从来不会厌倦生活&#xff0c;只是厌倦了那些毫无生气的生活方式。”把这句话稍微修改一下&#xff0c;放在职场也无比适用“我并不厌倦工作,只是厌倦了那些毫无…

第10章_创建和管理表

第10章_创建和管理表 1. 基础知识 1.1 一条数据存储的过程 存储数据是处理数据的第一步。只有正确地把数据存储起来&#xff0c;我们才能进行有效的处理和分析。否则&#xff0c;只能是一团乱麻&#xff0c;无从下手。 那么&#xff0c;怎样才能把用户各种经营相关的、纷繁复…

从零玩转设计模式之建造者模式-jianzaozhemoshi

title: 从零玩转设计模式之建造者模式 date: 2022-12-08 18:15:30.898 updated: 2022-12-23 15:35:58.428 url: https://www.yby6.com/archives/jianzaozhemoshi categories: - 设计模式 tags: - 设计模式 - 建造者模式 什么是建造者模式? 建造者模式是一种软件设计模式&…

突发!OpenAI 重磅发布 ChatGPT iOS 客户端!无须手续费,直接开通Plus。

大家好&#xff0c;我是GG哥&#xff01; 今天凌晨&#xff0c;OpenAI又重磅宣布推出ChatGPT的 iOS移动版本。也就是说&#xff0c;从今天开始iOS用户将可以在手机和iPad上免费下载和使用ChatGPT。 整体来说&#xff0c;iOS移动端的ChatGPT主打简洁流畅的风格&#xff0c;全力提…

Qt C++5.9开发指南

第1章 认识Qt 1.1 Qt简介 1、Qt是一套应用程序开发类库&#xff0c;但与MFC不同&#xff0c;Qt是跨平台开发类库。 2、跨平台意味着只需要编写一次程序&#xff0c;在不同平台上无需改动或只是需要少许改动后再编译&#xff0c;就可以形成不同平台上运行的版本。 1.2 Qt的获取与…

Python中的字典学习笔记

字典的格式&#xff1a;{"key":"value"} key表示数据的含义&#xff0c;value表示对应的数据的值字典是一种可变的数据类型&#xff0c;从python3.7开始&#xff0c;字典是有序的。 字典创建的方式 1、通过{}&#xff0c;要使用key:value的格式&#xff0c…