MySQL事务的概念

一、事务定义

  • 事务:事务是一个最小的不可在分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务是一个最小的工作单元)
  • 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成。
  • 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。

二、转账操作理解事务

我们来看一个真实的转账业务,表名为t_act(账户、余额),用户1需要向用户2转账100元

actno        balance
1            500
2            100

进行转账操作

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;
以上两台DML语句必须同时成功或者同时失败。最小单元不可再分,当第一条DML语句执行成功后,
并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下;
这个记录是在内存中完成的;当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步。
若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务

三、事务的四大特性

1.原子性(A):指一个事物是一个不可分割的工作单位,其中的操作要么都成功,要么都失败.
当事务发现有些语句不能执行时,需要将数据恢复到事务执行前,通过undo log实现。

undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,
在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,
当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。

2.持久性(I): 指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

持久性问题的产生:
背景:Mysql为了保证存储效率,每次读写文件都是先对缓存池(Buffer Pool)操作,缓冲池再定期刷新到磁盘中(这一过程称为刷脏)。
产生:由于数据不是直接写到磁盘,那么如果主机断电,就会有一部分数据丢失。
解决:通过重做日志(redo log)恢复数据。在每次修改数据之前,都会将相应的语句写到redo log中,如果主机断电,那么再次启动时可通过redo log回复。
拓展:redo log也需要在事务提交时将日志写入磁盘,它比缓冲池写入快的原因有两点:redo log是追加文件写,属于顺序IO,缓冲池是属于随机IO,且刷脏是以页为单位,有一点修改就要整页写入。

3.隔离性(D): 隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响。
下边讲到的事务并发问题就是隔离性的问题,MVCC就是解决这些问题的。

4.一致性©:指事务执行结束后,数据库的完整性约束没有被破坏,开始1000块钱,后面转账结束了,也得是1000块钱。

实现:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。

四、和事务相关的术语

  • 开启事务:Start Transaction
  • 事务结束:End Transaction
  • 事务提交: Commit Transaction
  • 事务回滚: Rollback Transaction

五、在MySQL中,事务提交与回滚

对t_act进行提交和回滚操作
(1).提交操作(非事务成功)

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

在这里插入图片描述
(2).提交操作(非事务失败)

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

在这里插入图片描述
(3).提交操作(事务成功)

  • start transaction #开始事务
  • DML语句
  • commit #事务提交
start transaction;#手动开启事务
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;
commit;#commit之后即可改变底层数据库数据

在这里插入图片描述
(4).提交操作(事务失败)

start transaction;#手动开启事务
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2w; #这个地方故意让第二个语句出错
commit;#commit之后即可改变底层数据库数据

在这里插入图片描述

(5)回滚操作(事务失败)

回滚操作指的是当我们事务提交失败的时候,就需要我们将数据回滚到失败前的时间段
比如,delete一张表,忘加限制条件,整张表没了。
误操作后,能快速回滚数据是非常重要的。

  • start transaction
  • DML语句
  • rollback
start transaction;#手动开启事务
delete from t_act;
rollback;

五、事务的并发问题

**1.脏读:**事务A读取到了事务B修改但未提交的数据。
在这里插入图片描述

通俗的讲,当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,
这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,
那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

**2.不可重复读:**事务A查询同一条语句的前后结果不一样。
在这里插入图片描述

在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据。
那么,在第一个事务的两次读数据之间。由于第二个事务的修改,
那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,
因此称为不可重复读,即原始读取不可重复。

3.幻读:

指当事务不是独立执行时发生的一种现象,例如 第一个事务对一个表中的数据进行了查询,
这种查询涉及到表中的全部数据行。同时,第二个事务向表当中添加了一行数据,
那么,以后就会发生操作第一个事务的用户发现表中还有没有相关的数据没有查询到,
就好像发生了幻觉一样。

在这里插入图片描述

六:事务的隔离等级

为了解决并发所产生的问题,我们提出了事务的隔离级别,隔离级别越高,解决并发产生的问题越多。
背景知识: 读锁和写锁,在读数据时上读锁,在写数据时上写锁。
数据上读锁后不能被其他事务修改,直到读锁释放。
数据上写锁其他事务不能读也不能修改。

隔离性的隔离级别
1.读未提交 read uncommitted
2.读已提交 read committed
3.可重复读 repeatable read
4.串行化 serializable

读未提交 read uncommitted

事物A和事物B,事物A未提交的数据,事物B可以读取到。
这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别。
三种并发问题都没解决。

演示:

1.创建表:
create table t_user(id int primary key auto_increment,username varchar(255));

设置读未提交的隔离级别

set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

MySQL8中隔离级别的变量跟之前的版本不一样,之前是tx_isolation,MySQL8改成了transaction_isolation。
在这里插入图片描述

读已提交 read committed

事物A和事物B,事物A提交的数据,事物B才能读取到
这种隔离级别高于读未提交
换句话说,对方事物提交之后的数据,我当前事物才能读取到
这种级别可以避免“脏数据”
这种隔离级别会导致“不可重复读取”
Oracle默认隔离级别

设置读已提交的隔离级别

set global transaction isolation level read committed;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

在这里插入图片描述
可以看出,插入但没有提交,是读不出来的,提交之后才能读出来。

可重复读 repeatable read

- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 事务B是可重复读取数据
- 这种隔离级别高于读已提交
- 换句话说,对方提交之后的数据,我还是读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- 比如1点和2点读到数据是同一个
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”

设置可重复读的隔离级别

set global transaction isolation level repeatable read;
查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

在这里插入图片描述
可见,无论是删除还是添加,commit后都是成功的,但是另一边却还是读出原来的数据,这就是可重复读,读取的是备份数据不是真正的数据。

串行化 serializable

事务A和事务B,事务A在操作数据库时,事务B只能排队等待
这种隔离级别很少使用,吞吐量太低,用户体验差
这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,
而不并发

设置串行化的隔离级别

set global transaction isolation level serializable;查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

在这里插入图片描述

七:隔离级别与一致性的关系

在这里插入图片描述

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

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

相关文章

Java基于微信小程序的医院挂号小程序,附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

Jenkins 2.426.3新版设置中文

1. 插件页面显示无法联网 ,点击Plugins一直提示连接超时,设置公司代理后 2. 稍等一会儿点击如下图,插件就出来了,然后输入Locale进行下载 3. 以下是我下载安装好的 4.打开设置,找到Locale选项,设置成zh_CN…

第13章 网络 Page738~741 13.8.3 TCP/UDP简述

libcurl是C语言写成的网络编程工具库,asio是C写的网络编程的基础类型库 libcurl只用于客户端,asio既可以写客户端,也可以写服务端 libcurl实现了HTTP\FTP等应用层协议,但asio却只实现了传输层TCP/UDP等协议。 在学习http时介绍…

【IO流】FileOutputStream 字节输出流

FileOutputStream 字节输出流 1. 概述2. 作用3. 书写步骤4. 构造方法5. 换行写6. 续写7. 注意事项 1. 概述 FileOutputStream 是 Java 中用于向文件写入字节数据的输出流类。它用于创建一个文件输出流,该流用于将数据写入文件。 功能:FileOutputStream …

C高级D5作业

1.#!/bin/bash read -p "请输入一个字符>>" -n 1 c echo case $c in [[:lower:]]) echo "小写" ;; [[:upper:]]) echo "大写" ;; [1-9]) echo "数字" ;; …

阿里云香港网络线路类型BGP(多线)精品延迟测试

阿里云香港等地域服务器的网络线路类型可以选择BGP(多线)和 BGP(多线)精品,普通的BGP多线和精品有什么区别?BGP(多线)适用于香港本地、香港和海外之间的互联网访问。使用BGP&#xf…

C++ //练习 7.27 给你自己的Screen类添加move、set和display函数,通过执行下面的代码检验你的类是否正确。

C Primer&#xff08;第5版&#xff09; 练习 7.27 练习 7.27 给你自己的Screen类添加move、set和display函数&#xff0c;通过执行下面的代码检验你的类是否正确。 Screen myScreen(5, 5, X); myScreen.move(4, 0).set(#).display(cout); cout<<"\n"; myScr…

循环、数组、match

for循环 循环&#xff1a;周而复始 For&#xff08;临时变量&#xff1b;循环条件&#xff1b;腰间变更&#xff09;{ 循环体 } For循环可以嵌套 while循环 声明变量 While&#xff08;条件&#xff09;{ 循环体 变量的变化} do while循环 do{ 执行语句&#xff1b; …

LeetCode Python - 23.合并K个升序链表

目录 题目答案运行结果 题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#xff1a;[1,1,2,3,4,4,5,6] 解释&a…

Open CASCADE学习|直纹曲面(ruled surface)

直纹曲面是一类特殊的曲面&#xff0c;在几何学和微分几何中都有研究。它的主要特性是&#xff0c;曲面上的每一点都有至少一条直线经过。换句话说&#xff0c;直纹曲面可以由一条直线通过连续运动构成。在三维欧几里德空间中&#xff0c;最常见的直纹曲面是平面、柱面和锥面&a…

MySQL数据库进阶第一篇(存储引擎与Linux系统上安装MySQL数据库)

文章目录 一、MySQL体系结构二、存储引擎介绍相关操作&#xff1a; 三、InnoDB 存储引擎简介四、MyISAM 存储引擎简介五、Memory 存储引擎简介六、存储引擎特点七、存储引擎的选择八、Linux系统上安装MySQL数据库1.用FinalShell远程连接Linux系统2.下载Linux版的MySQL安装包3.上…

代码随想录day23--回溯的应用2

LeetCode39.组合总和 题目描述&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates…

PyQt Python 使用 VTK ITK 进行分割 三维重建 医学图像可视化系统 流程

效果&#xff1a; 重建流程&#xff1a; 1. 输入 可以读取DICOM &#xff0c;nii nrrd 等数据 设置读取器以加载 DICOM 图像系列。 使用 itk::GDCMImageIO 作为 DICOM 图像的输入输出接口。 使用 itk::GDCMSeriesFileNames 获取指定路径下的所有 DICOM 文件名。 使…

Code Composer Studio (CCS) - Current and Local Revision

Code Composer Studio [CCS] - Current and Local Revision References 鼠标放在文件内的任意位置&#xff0c;鼠标右键 -> Compare With -> Local History -> Revision Time. References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

Doris ——SQL原理解析

目录 前言 一、Doris简介 二、SQL解析简介 2.1 词法分析 2.2 语法分析 2.3 逻辑计划 2.4 物理计划 三、Doris SQL解析的总体架构 四、Parse阶段 五、Analyze阶段 六、SinglePlan阶段&#xff08;生成单机逻辑Plan阶段&#xff09; 七、DistributedPlan计划&#xf…

SQL-Labs靶场“11-15”关通关教程

君衍. 一、十一关 基于POST单引号字符型注入1、源码分析2、联合查询注入3、报错注入 二、十二关 基于POST双引号字符型注入1、源码分析2、联合查询注入3、报错注入 三、十三关 基于POST单引号报错注入变形1、源码分析2、报错注入 四、十四关 基于POST双引号报错注入1、源码分析…

代码随想录day24--回溯的应用3

LeetCode93.修复IP地址 题目描述&#xff1a; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是…

使用八叉树模拟水和烟雾 Simulating Water and Smoke with an Octree Data Structure 论文阅读笔记

原文&#xff1a; Losasso, Frank, Frdric Gibou, and Ron Fedkiw. “Simulating water and smoke with an octree data structure.” Acm siggraph 2004 papers. 2004. 457-462. 引言 这篇文章扩展了 [Popinet 2003] 的工作&#xff0c;拓展到表面自由流&#xff0c;并且使…

Oracle 基础入门指南

一、什么是Oracle&#xff1f; Oracle是一款由美国Oracle公司开发的关系型数据库管理系统。它支持SQL查询语言&#xff0c;并提供了丰富的功能和工具&#xff0c;用于管理大规模数据存储、处理和访问。Oracle被广泛应用于企业级应用中&#xff0c;包括金融、电信、零售等各行各…

第12章 反射

12.1 反射概述 Java的反射&#xff08;reflection&#xff09;机制是指在程序的运行状态中&#xff0c;可以构造任意一个类的对象&#xff0c;可以得到任意一个对象所属的类的信息&#xff0c;可以调用任意一个类的成员变量和方法&#xff0c;可以获取任意一个对象的属性和方法…