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

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才能看到隔离级别的变化

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

猫头虎博主分享运维技巧: 解决RuntimeError: Expected all tensors to be on the same device

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Java基于SpringBoot+Vue的专家医院预约挂号系统,附源码

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

【C++航海王:追寻罗杰的编程之路】探寻实用的调试技巧

目录 1 -> 什么是bug&#xff1f; 2 -> 调试是什么&#xff1f;有多重要&#xff1f; 2.1 -> 调试是什么&#xff1f; 2.2 -> 调试的基本步骤 2.3 -> Debug和Release的介绍 3 -> Windows环境调试介绍 3.1 -> 调试环境的准备 3.2 -> 学会快捷键…

7-17 爬动的蠕虫

题目链接&#xff1a;7-17 爬动的蠕虫 一. 题目 1. 题目 2. 输入输出样例 3. 限制 二、代码 1. 代码实现 #include <stdio.h>int main(void) {unsigned int n, u, d;unsigned int minute, high;if (scanf("%d %d %d", &n, &u, &d) ! 3) {retur…

【CKA模拟题】边车容器Shared-Volume的具体用法

Useful Resources: Persistent Volumes Claim , Pod to Use a PV 题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetes An existing nginx pod, my-pod-cka and Persistent Volume Claim…

GIF在线生成器

上传图片就能生成GIF的前端WEB工具 源码也非常简单 <!DOCTYPE html> <html lang"zh" class"dark"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1, m…

设计模式学习笔记 - 设计模式与范式 -行为型:8.状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

概述 本章学习状态模式。在实际的开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上看&#xff0c;它有点像我们之前讲到的组合模式。 状态模式一般用来实现状态机&#xff0c;而状态机常用在游戏、工…

前端三剑客 —— JavaScript (第一节)

目录 回顾内容 1.弹性布局 2.网格布局 JavaScript 概述 发展 浏览器 什么是Javascript JavaScript 能干什么 JavaScript需要的环境 JavaScript初体验 基本数据 JS书写方式 行内JS 页面JS 外部JS 1&#xff09;创建外部JS文件 2&#xff09;编写页面 对话框 警…

类的函数成员(四):赋值函数

一.赋值函数是什么&#xff1f; 1.1 运算符的重载 运算符的重载实际是一种特殊的函数重载&#xff0c;必须定义一个函数&#xff0c;并告诉C编译器&#xff0c;当遇到该重载的运算符时调用此函数。这个函数叫做运算符重载函数&#xff0c;它通常为类的成员函数。 定义运算符重…

TCP 重传、滑动窗口、流量控制、拥塞控制(计算机网络)

重传机制 TCP 针对数据包丢失的情况&#xff0c;会用重传机制解决。 接下来说说常见的重传机制&#xff1a; 超时重传快速重传SACKD-SACK 超时重传 重传机制的其中一个方式&#xff0c;就是在发送数据时&#xff0c;设定一个定时器&#xff0c;当超过指定的时间后&#xff0c…

HarmonyOS实战开发-如何使用 geolocation 实现获取当前位置经纬度

介绍 本示例使用 geolocation 实现获取当前位置的经纬度,然后通过 http 将经纬度作为请求参数,获取到该经纬度所在的城市。通过 AlphabetIndexer 容器组件实现按逻辑结构快速定位容器显示区域。 效果预览 使用说明 1.进入主页,点击国内热门城市,配送地址会更新为选择的城…

javaScript 事件循环 Event Loop

一、前言 javaScript 是单线程的编程语言&#xff0c;只能同一时间内做一件事情&#xff0c;按照顺序来处理事件&#xff0c;但是在遇到异步事件的时候&#xff0c;js线程并没有阻塞&#xff0c;还会继续执行&#xff0c;这又是为什么呢&#xff1f; 二、基础知识 堆&#x…

vivado HDL 例化调试探测流程概述

HDL 例化调试探测流程概述 HDL 例化探测流程涉及在 HDL 设计源代码中直接手动自定义、例化和连接各种调试核组件。下表中显示了 Vivado 工具中此流程所支持的新调试核。 新的 ILA 核相比于传统 ILA v1.x 核具有以下 2 大优势 &#xff1a; • 可搭配集成的 Vivado Log…

FreeRTOS临界段代码保护和任务调度器的挂起与恢复学习

FreeRTOS临界段代码保护和任务调度器的挂起与恢复学习 临界段代码保护 所谓临界段代码保护就是指必须完成运行&#xff0c;不能被打断的代码段。比如需要严格按照时序除初始化的外设&#xff1a;IIC、SPI&#xff0c;再或者因为系统自身需求和用户需求。 FreeRTOS 在进入临界…

发型不满意试试开源AI换发型HairFastGAN;前OpenAI员工Karpathy1000纯C语言写完GPT-2

✨ 1: HairFastGAN 开源AI换发型 HairFastGAN 是一种先进的技术&#xff0c;专门设计用于在不同图片之间传输发型。这意味着如果你有一张人物的图片和另一张你喜欢的发型的图片&#xff0c;HairFastGAN 能够将你喜欢的那个发型复制到人物的头上&#xff0c;而且看起来非常自然…

强化学习MPC——(二)

本篇主要介绍马尔科夫决策&#xff08;MDP&#xff09;过程&#xff0c;在介绍MDP之前&#xff0c;还需要对MP&#xff0c;MRP过程进行分析。 什么是马尔科夫&#xff0c;说白了就是带遗忘性质&#xff0c;下一个状态S_t1仅与当前状态有关&#xff0c;而与之前的状态无关。 为…

深入浅出索引(上)

提到数据库索引&#xff0c;我想你并不陌生&#xff0c;在日常工作中会经常接触到。比如某一个 SQL 查询比较慢&#xff0c;分析完原因之后&#xff0c;你可能就会说“给某个字段加个索引吧”之类的解决方案。但到底什么是索引&#xff0c;索引又是如何工作的呢&#xff1f;今天…

NPW(监控片的)上---基础知识要点精讲

半导体的生产过程已经历经数十年的发展&#xff0c;其中主要有两个大的发展趋势&#xff0c;第一&#xff0c;晶圆尺寸越做越大&#xff0c;到目前已有超过70%的产能是12寸晶圆&#xff0c;不过18寸晶圆产业链推进缓慢&#xff1b;第二&#xff0c;电子器件的关键尺寸越做越小&…

【面试题】如何在级别用户中检查用户名是否存在?

前言 不知道大家有没有留意过&#xff0c;在使用一些app或者网站注册的时候&#xff0c;提示你用户名已经被占用了&#xff0c;比如我们熟知的《英雄联盟》有些人不知道取啥名字&#xff0c;干脆就叫“不知道取啥名”。 但是有这样困惑的可不止他一个&#xff0c;于是就出现了…

转圈游戏——快速幂

目录 题目 思路 代码 题目 思路 每个小朋友移动一次的位置为&#xff0c;移动 q 次的位置则为。那么题目要求移动 &#xff0c;最后的位置为 。 但 的范围是&#xff0c;而总的移动次数是 。时间复杂度是在&#xff0c;因此是一定不能硬算的&#xff0c;肯定会超时。那么该…