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.hqwc.cn/news/479341.html

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

相关文章

农田气象站对园区环境有什么影响

农田气象站对园区环境没有负面影响,反而有多方面的积极影响。【TH-NQ8】 首先,农田气象站可以实时监测和记录田间的气象数据,包括温度、湿度、光照、风速等,有助于管理者掌握田间气象变化,及时更改耕种策略&#xff0…

MySQL篇之分库分表

一、为什么要分库分表 1.目的 1. 分担了访问压力 2. 解决存储压力 2.分库分表的时机 1. 前提,项目业务数据逐渐增多,或业务发展迅速,单表的数据量达1000W或20G以后。 2. 优化已解决不了性能问题(主从读写分离、查询索引…&am…

nrm 镜像源管理工具

1、什么是nrm nrm(npm registry manager )是npm的镜像源管理工具。它可以快速在让你在本地源之间切换。 2、安装 npm install -g nrm 3、查看本地源(nrm ls) 4、切换 (nrm use ***) 5 、测试速度(nrm test ***&…

vue3实现瀑布流布局组件

先看效果图 直接上代码 utils.js // 用于模拟接口请求 export const getRemoteData (data 获取数据, time 2000) > {return new Promise((resolve) > {setTimeout(() > {console.log(模拟获取接口数据, data)resolve(data)}, time)}) }// 获取数组随机项 export…

【高阶数据结构】B+树

文章目录 1. B树的概念2. B树的查找3. B-树 VS B树4. B 树的插入分析 1. B树的概念 B树是B树的变形,是在B树基础上优化的多路平衡搜索树,B树的规则跟B树基本类似,但是又在B树的基础上做了一些改进优化。 一棵m阶的B树需满足下列条件&#x…

推荐一个内网穿透工具,支持Windows桌面、Linux、Arm平台客户端

神卓互联是一款常用的内网穿透工具,它可以将本地服务器映射到公网上,并提供域名或子域名给外部访问。神卓互联具有简单易用、高速稳定的特点,支持Windows桌面版、Linux版、Arm版客户端,以及硬件等。 神卓互联内网穿透技术简介 企…

HarmonyOS开发篇—数据管理(分布式数据服务)

分布式数据服务概述 分布式数据服务(Distributed Data Service,DDS) 为应用程序提供不同设备间数据库数据分布式的能力。通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。通过结合帐号、应用和数据库三元组&#xf…

【力扣 - 二叉树的最大深度】

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 提示&#xff1a; 树中节点的数量在 [0, 10^4] 区间内。 -100 < Node.val < 100方法一&#xff1a;深度优先搜索 思路与算法 如…

杨氏矩阵和杨辉三角

杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 分析 若要满足要求时间复杂度小于O(N)&#xff0c;就不能每一行一个个…

7款自媒体人ai写作必备的免费工具,快速高效运营 #AI写作#知识分享#知识分享

在当今信息爆炸的时代&#xff0c;写作成为了人们表达思想、分享知识和传递情感的重要方式之一。对于很多人来说&#xff0c;写作并非易事。我们会陷入困境&#xff0c;无法找到灵感&#xff0c;我们会苦恼于语言表达的准确性&#xff0c;还有时候我们可能遭遇到了创作瓶颈&…

Cesium for Unreal 从源码编译到应用——创建三维地球

一、基础环境 Unreal Engine 5.3 编译好的CesiumForUnreal插件 Cesium ion 账号 二、创建新工程 启动Unreal Engine&#xff0c;选择游戏->空白模板&#xff0c;输入项目名称。 打开内容浏览器&#xff0c;在内容文件夹中新建Maps文件夹&#xff0c;然后在里面添加新的…

Android 沉浸式状态栏

过时的API //设置默认隐藏虚拟按键&#xff0c;虚拟按键显示后为半透明protected open fun hideNavigationBarAndFullScreen() {val flags: Int// This work only for android 4.4flags if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {// This work only for a…