一文弄懂mysql事务

news2024/11/29 2:40:51

首先,什么是事务呢?

事务就是由单独单元的一个或多个sql语句组成, 在这个单元中, 每个sql的语句都是相互依赖的, 而整个单独单元作为一个不可分割的整体存在, 类似于物理当中的原子(一种不可分割的最小单位)

通俗的来讲就是, 事务就是一个整体, 里面的内容要么都执行成功, 要么都不成功, 不可能存在部分执行成功而部分执行不成功的情况

就是说如果单元中某条sql语句一旦执行失败或者产生错误, 那么整个单元将会回滚(返回最初状态)所有受到影响的数据将返回到事务开始之前的状态, 但是如果单元中的所有sql语句都执行成功的话, 那么该事务也就被顺利执行

大家都知道, 我们的数据就是通过各种不同的技术存储引擎来引导存储的, 不同的存储引擎, 都有各自的特点. 在mysql中,常用的存储引起有innodb, mysiam, memor等.其中innodb支持事务(transeaction), 而myisam, memory等不支持事务

可以通过show engines;语句来查看mysql支持的存储引擎

 一 事务的四个特性(ACID)

  • 原子性: 指事务是一个不可分割的最小工作单位, 事务中的操作只有都发生和都不发生的两种情况
  • 一致性: 事务必须使数据库从一个一致状态变换到另外一个一致状态, 其他事务看到要么是最开始没转账的状态, 要么是转账成功后的状态, 忽略中间态
  • 隔离性: 一个事务的执行不能被其它事务干扰, 并发执行的各个事物之间不能互相干扰
  • 持久性: 一个事务一旦提交成功,  持久化到硬盘

二 事务的分类

事务分为隐式事务和显示事务两种 我们的dml语句(insert, update,delete)就是隐式事务

1. 隐式事务: 该事务没有明显的开启和结束标记, 它们都具有自动提交事务的功能; 不妨思考一下, update语句修改数据时, 是不是对表中的数据进行改变了, 它的本质其实就相当于一个事务

举例: 张三同学买了一个杯子99元, 是不是就是update语句对字段name为张三的同学的余额balance进行减99元的处理呢?代码如下

在这里插入图片描述

 2. 显示事务: 该事务具有明显的开启和结束标记; 也是本文重点要将的东西 使用显示事务的前提是你得先把自动提交事务的功能给禁用, 禁用自动提交功能就是设置autocommit变量值为0(0:禁用 1:开启)

先查看下当前autocommit变量值, 发现当前处于开启自动提交事务的状态

在这里插入图片描述

 禁用自动提交事务的功能并查看状态

在这里插入图片描述

 三 开启事务的步骤

在这里插入图片描述

#步骤一:开启事务(可选)
start transaction;
#步骤二:编写事务中的sql语句(insert、update、delete)
#这里实现一下"李二给王五转账"的事务过程
update t_account set balance = 50 where vname = "李二";
update t_account set balance = 130 where vname = "王五";
#步骤三:结束事务
commit; #提交事务
# rollback; #回滚事务:就是事务不执行,回滚到事务执行前的状态

运行结果:在这里插入图片描述

 四. 事务并发时出现的问题

但是呢, 因为某一时刻不可能总只有一个事务在运行, 可能出现A在操作t_account表中的数据, B也同样在操作t_account表, 那么就会出现并发问题, 对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采用必要的隔离机制, 就会发生以下各种并发问题

  • 脏读: 对于两个事务t1, t2, t1读取了已经被t2更新但是没有被提交的字段后, 若t2回滚, t1读取的内容就是临时且无效的
  • 不可重复读: 对于两个事务t1, t2, t1读取了一个字段, 然后t2更新了该字段, t1再读取同一个字段, 值就不一样了
  • 幻读: 对于两个事务t1,t2, t1在A表中读取了一个字段, 然后t2又在A表中插入了一些新的数据时, t1再读取该表时, 就会发现神不知鬼不觉地多了几行了...

所以, 为了避免以上出现的各种问题, 我们就必须要采取一些手段, mysql数据库系统提供了4种事务的隔离级别, 用来隔离并发运行的各个事务, 是的它们相互不受影响, 这就是数据库事务的隔离性

五. 事务的隔离级别

mysql种的四种事务隔离级别如下:

1. read uncommitted(读未提交): 允许事务读取未被其他事务提交的数据 (最低级别)

2. read committed(读已提交): 只允许事务读取已经被它是事务提交的数据(可以避免脏读)

3. repeatable read(可重复读): 确保事务可以多次读取相同的行, 在这个事务持续期间, 禁止其他事务对这个字段修改(避免脏读, 不可重复读)

4. serializable(串行化): 确保事务可以多次读取相同的行, 在这个事务持续期间,禁止其他事务对这个表修改, 锁表性能十分低下

一个事务与其他事务隔离的程度称之为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离几倍对应不同的干扰程度, 隔离级别越高, 数据的一致性就越好, 但并发性能就越差

这个通过一个例子简单介绍下并发:

一个人边开开车边打电话, 首先, 人只有一个大脑(cpu), 但是在同一时刻它却在执行2件事, 其实内部就是它的大脑在不同的切换, 之所以jc不允许司机边开车边打电话, 就是怕人脑在那一瞬间切换不过来, 从而导致交通事故的发生, 并发和这个例子是差不多的意思 但是这里, 电脑cpu可比人脑块多了, 所以出错的概率也相对来说小很多

接下来, 演示下, 集中不同事务隔离级别下发生的情况

在演示之前, 还需要知道如何查看和设置事务的隔离级别

语法:select @@tx_isolation;

#设置当前mysql连接的隔离级别:
set session transaction isolation level read uncommitted;
#设置数据库系统的全局的隔离级别:
set global transaction isolation level read uncommitted;

注意: 当前mysql连接的隔离级别和mysql全局的隔离级别的区别是什么?

如果只设置当前的隔离级别, 也就是session, 那么另外一个并发的session的隔离级别不受当前连接的影响, 也就是默认的repeatable read

但是如果是设置全局的事务隔离级别, 则整个mysql数据库(包括所有打开的session)的隔离级别都会随之改变, 除非服务重启, 不然就不会恢复默认

两者仅仅一词之差, 其效果却天差地别

 好, 了解完如何设置事务的隔离级别之后, 下面将正式进入...呃呃呃, 等一下

这里的讲解狐妖是为了知道在并发情况下, 不同的事务隔离级别所表现出的不同特点, 那么自然还是要先模拟一下并发环境

 正片开始, 同志们打起精神

1. read uncommitted(读未提交)

首先,我们需要先将两个会话的事务隔离级别都设置为read uncommitted;语句如下:

在这里插入图片描述

 read uncommitted可以读到其它事务还没有提交的变更, 这里举例: 程序2对t_account表中的数据进行更改, 看程序1多次查询结果是否一致

在这里插入图片描述

可以看到程序2改变了t_account表中的vname字段, 将李二改为了张三, 但是程序1呢, 连续2个selelct查询语句的结果竟然不一致, 估计现在程序1的表情和你手机里面的第三个表情包一样, 这就是read uncommitted隔离级别的特点

不管你事务是否提交, 只要数据发生改变我就可以察觉到, 嘻嘻, 是不是感觉到很强大, 什么事情都逃不过它的法眼

接下来要看的是read committed(读已提交)

  • read committed(读已提交)

测试前一定要记住设置事务的隔离级别为read committed; 并且禁用自动提交事务(设置autocommite=0)

# 设置事务隔离级别为read committed
set session transaction isolation level read committed;
# 禁用自动提交事务功能
set autocommit = 0; 
#接下来的 repeatable read 隔离级别和 serializable 隔离级别也是同样的操作

在这里插入图片描述

 以上例子实现了王五为张三转账的事务, 可以看到程序2中事务提交前与提交后对程序1中的查询语句产生的影响, 第一个查询事务没提交结果, 第二次查询是事务提交后的结果, 相信上面的例子已经诠释了read commited的特点

  • repeatable read(可重复读)

该隔离级别为mysql的默认隔离级别, 它对某字段操作时, 其他事务禁止操作该字段, 它总能保持你读取的数据是一致的, 以下代码中, 程序1模拟"王五向张三转30元", 程序2则在程序1在处理事务时, 对张三的余额进行清空处理

在这里插入图片描述

程序1 操作t_account表时,程序2是无权对t_account表进行任何操作, 这里因为update语句会默认添加独占锁, 如果其他事务对特有的独占锁的记录进行修改时, 就会被阻塞

“ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction”;

其中文意思是:“超过锁定等待超时;尝试重新启动事务”

 只有当程序1对t_account表操作结束后(结束事务后), 程序2才可以对t_account表进行操作

在这里插入图片描述

  • serializable(串行化)

该隔离模式下执行的事务在对某表进行操作期间, 禁止其他所有事务对该表进行任何操作

如果强行操作了也会报错(和上面错误一样), 因为serializable用的相对比较少, 这里就不做演示了, 理解就好

  • 事务的保存点(回滚点)

回滚点表示的就是使事务回滚到指定的回滚点

语法: savepoint 节点名称 ;

注意:保存点只允许搭配rollback回滚来使用,不能和commit一起使用

 已知表t_stu存在, 其数据如下

在这里插入图片描述

代码举例如下:

#禁用自动提交事务
set autocommit = 0;
 #开启事务
start transaction;
 #删除id为2的记录
delete from t_stu where id = 2;
 #设置保存点名为AA
savepoint AA;
 #删除id为3的记录
delete from t_stu where id = 3;
  #回滚到AA保存点处
rollback to AA;

 

可以看到id为2的李四被删除了, 而王五却还在, 就是因为事务回滚到了AA处, 所以为3的那条记录被回滚掉了

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

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

相关文章

大学生找工作的个人简历模板(合集)

大学生找工作的个人简历模板1 个人基本简历 姓名:-国籍:中国 目前所在地:__ 民族:汉族 户口所在地:__ 身材: 婚姻状况:未婚年龄:__岁 培训认证:诚信徽章: 求职…

swagger 入门指南

1. 写在最前面 最近在负责的服务,出现了客户接二连三的投诉 api 参数难以理解的问题。本着从「根本上解决问题」的思路,笔者思考了以下方案: 简化难以理解的参数,重新设计一版 api 优化 api 文档,更易于用户理解 1…

代码随想录算法训练营第四十一天| 343. 整数拆分、96.不同的二叉搜索树

整数拆分 题目链接:力扣 确定dp数组(dp table)以及下标的含义 dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。确定递推公式 然后有两种渠道得到dp[i]: 一个是j * (i - j) 直接相乘。 一个是j * d…

unit4

目录 carpenterovertakeremainderobjectivepasturedespitegulfshepherdinteriorchorusoppressgrinprofessionalresistantfosterleapembarkneutralelasticcirculateintimidatechopprimarystirappraisallayoutsurvivalentertainmoanlocatepublishpacehearingexplosivecricketvolt…

stable-diffusion-webui 快捷安装教程

简介 stable-diffusion-webui 是一个用来装载Stable Diffusion 模型的网页,可以方便的调用模型生成图片。 stable-diffusion-webui的github地址为:https://github.com/AUTOMATIC1111/stable-diffusion-webui 这个库的依赖很多,虽然代码里面有…

NUCLEO-F411RE RT-Thread 体验 (1) - GCC环境 RT-Thread 的移植

NUCLEO-F411RE RT-Thread 体验 (1) - GCC环境 RT-Thread 的移植 1、准备工作 a、用stm32cubemx新建一个工程。 时钟配置 st-link提供8M的mco输出,所以配置hse 8m,sysclk最高100M,设置如下: 配置LED 连接pa5,设…

机器学习-进化算法

进化算法 遗传算法(Genetic Algorithm,GA)crossovermutation 进化策略(Evolutionary Strategies,ES)基因编程(Genetic Programming)Multi-objective Evolutionary Algorithms 遗传算…

certbot 申请免费SSL证书、自动续期

简介 Certbot是一个免费、开源的软件,是Let’s Encrypt的客户端,Let’s Encrypt是证书颁发机构,它们之间使用ACME协议通信,Certbot是Lets Encrypt众多客户端的其中之一,Let’s Encrypt官网推荐CertBot,它能…

AIGC:关于人工智能的那些事

文章目录 前言人工智能发展史起步阶段:20世纪50年代至70年代知识工程阶段:20世纪80年代至90年代数据驱动阶段:2000年至今 人工智能包括哪些技术学习人工智能需要掌握的知识如何开发一个人工智能系统如何开发一个人脸识别系统人工智能未来发展…

mysql密码登录失败、服务启动失败和1045-Access denied for user ‘root‘@‘localhost‘

一、问题: 1.打开 navicate,双击localhost_3306,出现报错2002 - Can’t connect to server on ‘localhost’(10061) 2.查看mysql是否启动 控制面板——管理工具——服务 找到mysql服务,发现无法启动。 3.winR运行cmd&#xf…

windows install pandoc

文章目录 下载安装测试使用 下载 https://github.com/jgm/pandoc/releases 安装 pandoc-3.1.3-windows-x86_64.msi 直接双击一路默认即可。 但安装后并没有得到该命令,我们需要配置环境变量,找到安装的命令位置 C:\Users\XH\AppData\Local\Pandoc\p…

驱动多文件编译和驱动命令行传参

目录 1. 驱动的多文件编译 1.1. 准备两个文件 1.2. 修改Makefile文件 1.3. 执行Make命令生成.ko文件 2. 驱动模块传递参数 2.1. 传递一个参数 2.1.1. 函数原型分析 2.1.2. 撰写.c文件 2.1.3. 撰写makefile 2.1.4. 编译makefile并验证 2.2. 传递多个参数并使用modeinf…

线程的创建和使用(二)

1、线程的类和方法 Thread类是JVM用来管理线程的一个类,换句话说,每个线程都有唯一一个的Thread对象与之关联。 1.1、Thread的常见方法 方法说明Thread()创建线程对象Thread(Runnable target)使用Runnable对象创建线程对象Thread(String name)创建线程…

【SpringCloud-5】gateway网关

网关是干啥用的就不用再说了。 sringcloud中的网关,第一代是zuul,但是性能比较差(1.x是阻塞式的,2.x是基于Netty的),然后有了第二代GateWay,基于Reactor模型 异步非阻塞。 springcloud网关就是一…

经理的工作岗位职责描述10篇

经理的工作岗位职责描述(篇1) 1、销售工具的开发和制作 2、负责各类媒体、渠道的软文撰写,产品信息推广; 3、筹办重点客户,潜在客户的讲座论坛会议; 4、市场推广活动:展会seminar oadshow等活动 5、产品上市沟通&#…

IIC协议通信解析,内附完整代码。

一:硬件接口 1.1:功能引脚 1.2:IIC总线通信注意事项 二:通信协议 (1)空闲状态: (2)起始位: (3)有效数据位 (4&#x…

最近跳槽,压力真大...

前几天,跟个老朋友吃饭,他最近想跳槽去大厂,觉得压力很大,问我能不能分享些所谓的经验套路。 每次有这类请求,都觉得有些有趣,不知道你发现没有大家身边真的有很多人不知道怎么面试,也不知道怎…

【玩转Docker小鲸鱼叭】MacOS系统配置Docker镜像加速器

当我们通过 docker pull拉取镜像时,如果不指定仓库,默认从 Docker Hub (docker.io)获取镜像,而国内用户访问Docker Hub仓库时,通常速度很忙,经常超时导致拉取镜像失败,所以通常要通过…

上海亚商投顾:沪指震荡调整 CPO概念股持续大涨

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 沪指今日震荡调整,保险等权重板块走低,上证50跌超1.5%,创业板指较为抗跌。CPO、…

【新固态格式化】

新固态格式化 初始化硬盘 从管理进入磁盘管理 Windows 7及其以后的系统建议使用GPT MBR 是 Master Boot Record 的缩写,是一种传统而常用的磁盘布局。GPT 是 Globally Unique Identifier Partition Table 的缩写,是一种与 UEFI 相关的新磁盘布局。其…