MySQL事务以及并发访问隔离级别

news2024/11/22 8:54:48

MySQL事务以及并发问题

  • 事务
    • 1.什么是事务
    • 2.MySQL如何开启事务
    • 3.事务提交方式
    • 4.事务原理
    • 5.事务的四大特性(ACID)
  • 事务并发问题
    • 1.并发引起的三个问题
    • 2.事务隔离级别

事务

在 MySQL 中,事务支持是在引擎层实现的。MySQL 是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,下面介绍是以InnoDB 引擎来的。

1.什么是事务

在实际的业务开发中,有些业务操作要多次访问数据库。一个业务要发送多条SQL语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行,要么所有的SQL语句全部执行成功。如果其中有一条SQL语句失败,就进行事务的回滚,所有的SQL语句全部执行失败。

简而言之,事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败。

eg: 银行转账事务
	用户A向用户B转200块钱(事务包含两条sql语句);
	无异常发生状况下,A账户减掉200块钱,B账户增加200块钱;
	如果发生异常导致A账户扣掉钱,而B账户没有收到钱。或者A账户没有扣钱,但B账户收到钱了。这显然不符合业务逻辑;

注:在数据库中查询不会涉及到使用事务,事务都是 增删改。

2.MySQL如何开启事务

MySQL事务有关的SQL语句:

SQL语句描述
start transaction;开启手动控制事务
commit;提交事务
rollback;回滚事务

# 创建一个表:账户表.
create database transaction_test; 
# 使用数据库
use transaction_test;
# 创建账号表
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
# 初始化数据
insert into account values (null,'A',1000); 
insert into account values (null,'B',1000);

案例演示1:需求:演示提交事务,a给b转账200元。(成功)

-- 需求:A给B转账200元(演示提交事务)
-- 1.开启事务
start transaction;
-- 2.执行一组sql语句
-- 2.1 A账户扣去200
update account set money=money-200 where name='A';
-- 2.2 B账户添加200
update account set money=money+200 where name='B';
-- 3.提交事务(使sql生效)
commit;

案例演示2:演示回滚事务,a给b转账200元。(失败)

MySQL本身无法演示出现异常的状况

-- 需求:A给B转账200元(演示回滚事事务)
-- 1.开启事务
start transaction;
-- 2.执行一组sql语句
-- 2.1 A账户扣去200
update account set money=money-200 where name='A';

# 假设A给B转账中间发生异常,之后选择回滚sql语句

-- 2.2 B账户添加200
update account set money=money+200 where name='B';
-- 3.回滚事务(撤销sql语句)
rollback;

3.事务提交方式

自动提交事务(MySQL默认的事务操作方式)

手动提交事务(上方例子)

MySQL的每一条DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,执行完毕自动提交事务。

MySQL默认开始自动提交事务。如果我们想将几条DML语句视为同一个事务,需要开启手动提交事务。比如上面的转账案例

  • 如果我们想修改MySQL默认事务方式,将其改为手动提交。可以使用下面命令

    • -- 查看当前autocomit模式
      show variables like %commit%;
      

    • -- 设置自动提交的参数为OFF:
      set autocommit = 0;  -- 0:OFF  1:ON
      

      :设置autocommit为off状态,只是临时性的,下次重新连接MySQL,autocommit依然变为on状态。

4.事务原理

1562228567293

  1. 一个用户登录成功以后,服务器会创建一个临时日志文件。日志文件用来保存用户事务状态。
  2. 如果没有使用事务,则所有的操作直接写到数据库中,不会使用日志文件。
  3. 如果开启事务,将所有的写操作写到日志文件中。
  4. 如果这时用户提交了事务,则将日志文件中所有的操作写到数据库中。
  5. 如果用户回滚事务,则日志文件会被清空,不会影响到数据库的操作。

5.事务的四大特性(ACID)

1、隔离性(Isolation)

  • 多个用户并发的访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发的事务之间要相互隔离。

  • 一个事务的成功或者失败对于其他的事务是没有影响。2个事务应该相互独立。

eg:
a 给b转账 -----> 叫做事务A
c 给d 转账 -----> 叫做事务B
事务A和事务B之间不会相互影响。

2、持久性(Durability)

  • 指一个事务一旦被提交,它对数据库的改变将是永久性的,哪怕数据库发生异常,重启之后数据亦然存在。
eg:A=1000、B=1000转账
    开启事务
    A-200
    B+200
    提交
结果: A 800 B 1200
即使事务提交以后再发生异常,A和B的数据依然不会变。A就是800,B就是1200。

3、原子性(Atomicity)

  • 原子性是指事务包装的一组sql(一组业务逻辑)是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

4、一致性(Consistency)

  • 一个事务在执行之前和执行之后 数据库都必须处于一致性状态。如果事务成功的完成,那么数据库的所有变化将生效。如果事务执行出现错误,那么数据库的所有变化将会被回滚(撤销),返回到原始状态。

  • 事务的成功与失败,最终数据库的数据都是符合实际生活的业务逻辑。一致性绝大多数依赖业务逻辑和原子性。

eg:A=1000、B=1000转账
    开启事务
    A-200
    B+200
    提交
结果: A 800 B 1200
如果A转账失败了,那么B也得失败。不能转账之前一共是2000块钱,A扣钱,B不变,结果是1800。或者A不扣钱,B加钱,结果是2200。
**事务前后数据的完整性必须保持一致**

事务并发问题

1.并发引起的三个问题

​ 事务在操作时的理想状态:多个事务之间互不影响,如果隔离级别设置不当就可能引发并发访问问题。

​ 当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,之后会介绍解决方案“隔离级别”。

并发访问的问题含义
脏读一个事务读取到了另一个事务中尚未提交的数据。最严重,杜绝发生。
不可重复读一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是不一致的,这是事务update时引发的问题
幻读(虚读)一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同。这是insert或delete时引发的问题

1.脏读:指一个事务读取了另外一个事务未提交的数据。(非常危险)

​ 脏读具体解释如下图:注意 脏读的前提是没有事务的隔离性。

  • 说明:事务a首先执行转账操作,然后事务a还没有提交数据的情况下,事务b读取了数据库的数据。紧接着事务a执行回滚操作,导致事务b读取的结果和数据库的实际数据是不一样的。
  • 一个事务读取了另一个事务未提交的数据叫做脏读。

2.不可重复读:在一个事务内多次读取表中的数据,多次读取的结果不同。

  • 说明:事务b首先读取数据库的数据,然后事务a对数据修改并提交。之后事务b对数据库再次进行读取。这时发现在事务b中2次读取的结果不一致。

  • 一个事务内读取了另一个事务提交的数据。这个叫做不可重复读。

    • 例如: 银行想查询A账户的余额,第一次查询的结果是200元,A向账户中又存了100元。此时,银行再次查询的结果变成了300元。两次查询的结果不一致,银行就会很困惑,以哪次为准。
  • 和脏读不同的是:脏读读取的是前一事务未提交的数据,不可重复度 读取的是前一事务已提交的事务。

3.幻读(虚读):一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同

  • 说明:事务b首先读取数据的数量,然后事务a添加了一条数据,并且提交了。接着事务b再次读取了数据的数量。2次读取不一致。

  • 同一个事务内,2次读取的数据的数量不一致,叫做幻读或者虚读。

  • 虚读(幻读)和不可重复读的区别:

    • 不可重复读:强调的是数据内容的不一致。另一个事务是update操作。
    • 虚读(幻读):强调的数据的数量(记录数)的不一致。另一个事务是insert或者delete操作。

2.事务隔离级别

​ 通过以上面描述,我们发现如果不考虑事务的隔离性,会遇到脏读、不可重复读和虚读等问题。所以在数据库中我们要对上述三种问题进行解决。MySQL数据库规范规定了4种隔离级别,分别用于描述两个事务并发的所有情况。

上面的级别最低,下面的级别最高。“是”表示会出现这种问题,“否”表示不会出现这种问题。

级别名字隔离级别脏读不可重复读幻读数据库默认隔离级别
1读未提交read uncommitted
2读已提交read committedOracle和SQL Server
3可重复读repeatable readMySQL
4串行化serializable

image-20221116172342160

  • 安全和性能对比

    • 安全性:serializable > repeatable read > read committed > read uncommitted

    • 性能 : serializable < repeatable read < read committed < read uncommitted

  • 注:其实三个问题,开发中最严重的问题就是脏读,这个问题一定要避免,而关于不可重复读和虚读其实只是感官上的错误,并不是逻辑上的错误。就是数据的时效性,所以这种问题并不属于很严重的错误。如果对于数据的时效性要求不是很高的情况下,我们是可以接受不可重复读和虚读的情况发生的。

  • 查询全局事务隔离级别

    • show variables like '%isolation%';
      -- 或
      select @@tx_isolation;
      
  • 设置事务隔离级别

    • set global transaction isolation level 隔离级别;
      -- 如:
      set global transaction isolation level read uncommitted;
      set global transaction isolation level repeatable read;
      
    • 注:需要退出MySQL再进入MYSQL才能看到隔离级别的变化

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

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

相关文章

关于搭建电商独立站跨境电商接入主流电商平台API商品接口对于商品功能模块的巨大应用

功能设计 首先我们来看下mall项目中商品功能的设计&#xff0c;主要包括商品管理、添加\编辑商品、商品分类、商品类型、品牌管理等功能&#xff0c;这里的功能同时涉及前台商城和后台管理系统。 商品管理【接入主流电商平台商品API接口丰富自建商城商品】 在mall项目的后台管…

微信批量群发软件有哪款比较好用的?

微信有自带的群发助手&#xff0c;只能群发200个好友&#xff0c;比较有局限性。 我是做销售的&#xff0c;对于群发的需求特别大&#xff0c;我自己平时经常用WeB微信批量群发软件有哪款比较好用的&#xff1f;WeB&#xff0c;它满足了我的群发需求&#xff0c;用起来特别方便…

cocos 3.x版本如何基于ts在检视面板显示Enum枚举类型下拉列表

前言 网上搜索到的大多是基于js或者旧版本cocos。这里记录一下ts显示Enum的方案&#xff0c;cocos版本使用的3.8.2。 解决方案 方案一&#xff1a; import { _decorator, Component, TweenEasing } from cc; const { ccclass, property } _decorator;const MyTweenEasing …

C#.net6.0手术麻醉信息管理系统源码,智慧手术室管理平台源码

手术麻醉信息管理系统源码&#xff0c;自主版权的手麻系统源码 手术麻醉信息管理系统包含了患者从预约申请手术到术前、术中、术后的流程控制。手术麻醉信息管理系统主要是由监护设备数据采集子系统和麻醉临床系统两个子部分组成。包括从手术申请到手术分配&#xff0c;再到术前…

春秋云境CVE-2023-0562

简介 银行储物柜管理系统是一个基于网络的应用程序&#xff0c;用于处理存储银行客户贵重物品的银行储物柜。储物柜的所有详细信息都保存在数据库中。银行储物柜管理系统项目是使用 PHP 和 MySQLi 扩展开发的。 正文 进入靶场&#xff0c;首先就看到有个bankers&#xff0c;…

真快乐APP抢购源码实现

支持多个平台的自动 滑动验证码、选字验证码。缺点就是需要自己找一个验证码识别服务器,可以自己用python写一个,或者使用超级鹰(本篇教程就是使用它) 下面是实现源码 "ui"; Date.prototype.Format = function (fmt) {var o = {"M+": this.getMonth() …

常用的限流方案思路和实现

限流方案 1、计数器&#xff08;固定窗口&#xff09; 1.1、简介 计数器固定窗口算法是最基础也是最简单的一种限流算法。原理就是对一段固定时间窗口内的请求进行计数&#xff0c;如果请求数超过了阈值&#xff0c;则舍弃该请求&#xff1b;如果没有达到设定的阈值&#xf…

STM32学习笔记(10_1)- I2C通信协议

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 本期开…

JMeter+Grafana+influxdb 配置出现transaction无数据情况解决办法

JMeterGrafanainfluxdb 配置出现transaction无数据情况解决办法 一、问题描述二、解决方法 一、问题描述 如下图所示出现application有数据但是transaction无数据情况 二、解决方法 需要做如下设置 打开变量设置如下图打开两个选项 然后再进行后端监听器的设置 如下图所…

【VUE】ruoyi框架自带页面可正常缓存,新页面缓存无效

ruoyi框架自带页面可正常缓存&#xff0c;新页面缓存无效 背景&#xff1a; 用若依框架进行开发时&#xff0c;发现ruoyi自带的页面缓存正常&#xff0c;而新开发的页面即使设置了缓存&#xff0c;当重新进入页面时依旧刷新了接口。 原因&#xff1a;页面name与 getRouters …

3个 JavaScript 字符串截取方法

在 JavaScript 中&#xff0c;可以使用 substr()、slice() 和 substring() 方法截取字符串. substring() substring() 方法返回一个字符串在开始索引到结束索引之间的一个子集&#xff0c;或从开始索引直到字符串的末尾的一个子集。语法如下&#xff1a; str.substring(inde…

GT收发器64B66B设计(1)IP核配置和example design

文章目录 前言一、IP核配置1.1、编码方式1.2、字节对齐和逗号码 二、example design 前言 在前面我们基于GT收发器进行了PHY层设计&#xff0c;其中采用的编码方式为8B10B&#xff0c;为进一步提高传输效率&#xff0c;从本文开始&#xff0c;将采用基于GT高速收发器采用64B66…

DC/DC选型:了解电感参数的基本含义

电感是一种相对简单的元件&#xff0c;它由缠绕在线圈中的绝缘线组成。但当单个元件组合在一起&#xff0c;用来创建具有适当尺寸、重量、温度、频率和电压的电感&#xff0c;同时又能满足目标应用时&#xff0c;复杂性就会增加。 选择电感时&#xff0c;了解电感数据手册中标…

京西商城——基于viewset视图集开发评论接口

在使用GenericAPIView和Mixins开发时&#xff0c;确实可以大大提高编码的速度以及减少代码量&#xff0c;但是在一个视图里并不能实现5个基础的请求方法&#xff0c;要用两个视图类来完成。所以我们可以使用viewset&#xff08;视图集&#xff09;来将两个视图类合并 如果要使…

Docker实战教程 第2章 Docker基础

3-1 Docker介绍 什么是Docker 虚拟化&#xff0c;容器 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&…

职场聚餐:搭建沟通桥梁,促进团队凝聚力

在职场中&#xff0c;聚餐作为一种非正式的社交活动&#xff0c;不仅能够增进同事间的了解&#xff0c;还有助于提升团队凝聚力。本文将探讨职场聚餐的重要性以及如何组织一场成功的职场聚餐。 一、职场聚餐的重要性 1. 搭建沟通桥梁&#xff1a;职场聚餐为员工提供了一个轻松愉…

Java中线程详解

文章目录 相关概念多线程概念实现方式继承Thread类实现Runnable接口比较 常用方法线程安全产生的原因解决思想同步同步代码块同步方法Lock锁机制 死锁概念避免 状态线程间的通讯介绍方法 相关概念 并行&#xff1a;在同一时刻&#xff0c;有多个任务在多个CPU上同时执行并发&a…

【JAVASE】学习类与对象的创建和实例化

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 目标&#xff1a; 1. 掌握类的定义方式以及对象的实例化 2. …

QML嵌套页面的实现学习记录

StackView是一个QML组件&#xff0c;用于管理和显示多个页面。它提供了向前和向后导航的功能&#xff0c;可以在堆栈中推入新页面&#xff0c;并在不需要时将页面弹出。 ApplicationWindow {id:rootvisible: truewidth: 340height: 480title: qsTr("Stack")// 抽屉:…

语义分割交互式智能标注工具 | 澳鹏数据标注平台

随着人工智能应用的大规模落地&#xff0c;数据标注市场在高速增长的同时&#xff0c;也面临着标注成本的挑战。据IDC报告显示&#xff1a;数据标注在AI应用开发过程中所耗费的时间占到了25%&#xff0c;部分医学类应用一条数据的标注成本甚至高达20元。数据精度的高要求、强人…