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-200B+200提交
结果: A 800 B 1200
即使事务提交以后再发生异常,A和B的数据依然不会变。A就是800,B就是1200。

3、原子性(Atomicity)

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

4、一致性(Consistency)

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

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

eg:A=1000、B=1000转账开启事务A-200B+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.mzph.cn/news/798530.shtml

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

相关文章

Java开发测试(第一篇):Java测试框架JUnit5

目录 1.基本介绍 2.maven中安装JUnit5 3.使用 4.JUnit5命名规则 5.JUnit5常用注解 6.JUnit5断言 7.JUnit5多个类之间的继承关系 8.JUnit5参数化 &#xff08;1&#xff09;使用场景&#xff1a; &#xff08;2&#xff09;使用前需在pom.xml文件中导入依赖 &#xff…

AcWing 1388. 游戏(每日一题)

原题链接&#xff1a;1388. 游戏 - AcWing题库 玩家一和玩家二共同玩一个小游戏。 给定一个包含 N 个正整数的序列。 由玩家一开始&#xff0c;双方交替行动。 每次行动可以在数列的两端之中任选一个数字将其取走&#xff0c;并给自己增加相应数字的分数。&#xff08;双方…

TCP三次握手,四次挥手

TCP为什么四次挥手&#xff1f;而不是三次&#xff1f; 正常流程&#xff1a;服务接收到 客户端的 FIN请求后&#xff0c;会发送一个ACK响应&#xff0c;等待系统资源释放后&#xff0c;再发送FIN 请求给客户端&#xff0c;客户端再发送一个ACK响应。 若为三次&#xff1a;就是…

unsigned和int相加减的错误

先看代码 #include<cstring> #include<vector> using namespace std; int main() {string s "12345678";int n s.length();cout << "n-10" << n - 10 << endl;cout << "s.length() - 10" << s.len…

第九届蓝桥杯大赛个人赛省赛(软件类)真题C 语言 A 组-航班时间

#include<iostream> using namespace std;int getTime(){int h1, h2, m1, m2, s1, s2, d 0;//d一定初始化为0&#xff0c;以正确处理不跨天的情况 scanf("%d:%d:%d %d:%d:%d (%d)", &h1, &m1, &s1, &h2, &m2, &s2, &d);return d …

基于Arduino nano配置银燕电调

1 目的 配置电调&#xff0c;设置电机转动方向&#xff0c;使得CW电机朝顺时针方向转动&#xff0c;CCW电机朝逆时针转动。 2 步骤 硬件 Arduino nano板子及USB线变阻器银燕电调EMAX Bullet 20A朗宇电机 2205 2300KV格氏电池3S杜邦线若干接线端子 软件 BLHeliSuite 注意…

数据库表设计18条黄金规则

前言 对于后端开发同学来说&#xff0c;访问数据库&#xff0c;是代码中必不可少的一个环节。 系统中收集到用户的核心数据&#xff0c;为了安全性&#xff0c;我们一般会存储到数据库&#xff0c;比如&#xff1a;mysql&#xff0c;oracle等。 后端开发的日常工作&#xff…

算法-数论-蓝桥杯

算法-数论 1、最大公约数 def gcd(a,b):if b 0:return areturn gcd(b, a%b) # a和b的最大公约数等于b与a mod b 的最大公约数def gcd(a,b):while b ! 0:cur aa bb cur%bpassreturn a欧几里得算法 a可以表示成a kb r&#xff08;a&#xff0c;b&#xff0c;k&#xff0c…

2024最新软件测试八股文,能不能拿心仪Offer就看你背得怎样了

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Linux - mac 装 mutipass 获取 ubuntu

mutipass &#xff1a;https://multipass.run/docs/mac-tutorial mutipass list mutipass launch --name myname mutipass shell myname 获取 root权限&#xff1a; sudo su

生成式人工智能与 LangChain(预览)(上)

原文&#xff1a;Generative AI with LangChain 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 一、生成模型是什么&#xff1f; 人工智能&#xff08;AI&#xff09;取得了重大进展&#xff0c;影响着企业、社会和个人。在过去的十年左右&#xff0c;深度学习已经发…

副业选择攻略:如何找到最适合自己的那一个?

大家好&#xff0c;我是木薯。今天有个新人伙伴来咨询客服&#xff1a;新手适不适合在水牛社上做副业&#xff1f;什么样的副业适合自己&#xff1f; 这种问题其实对我们来说已经见得太多太多了&#xff0c;归其原因是因为自己对副业没有一个清晰的自我认知&#xff0c;从而感觉…

基于LEAP模型的能源环境发展、碳排放建模预测及不确定性分析

在国家“3060”碳达峰碳中和的政策背景下&#xff0c;如何寻求经济-能源-环境的平衡有效发展是国家、省份、城市及园区等不同级别经济体的重要课题。根据国家政策、当地能源结构、能源技术发展水平以及相关碳排放指标制定合理有效的低碳能源发展规划需要以科学准确的能源环境发…

Spring——框架介绍

每一个Java技术中都会存在一个“核心对象”&#xff0c;这个核心对象来完成主要任务为了得到核心对象&#xff0c;需要创建若干个辅助对象&#xff0c;从而导致开发步骤增加JDBC中 JDBC 核心对象——PreparedStatement 通过DriverManager得到数据库厂商提供的Driver对象DriverM…

京东云轻量云主机8核16G配置租用价格1198元1年、4688元三年

京东云轻量云主机8核16G服务器租用优惠价格1198元1年、4688元三年&#xff0c;配置为8C16G-270G SSD系统盘-5M带宽-500G月流量&#xff0c;华北-北京地域。京东云8核16G服务器活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云8核16G服务器优惠价格 京东云…

MySQL数据库基础--存储引擎

MySQL体系结构 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理&#xff0c;授权认证&#xff0c;及相关的安全方案&#xff0c;服务器也会为安全接入的每个客户端验证他所具有的操作权限。 服务层 第二层架构主要完成大多数的核心服务功…

【C++入门】缺省参数、函数重载与引用

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

就业班 第二阶段(python) 2401--4.3 day2 python2

七、标准数据类型 1、为什么编程语言中要有类型 类型有以下几个重要角色&#xff1a; 对机器而言&#xff0c;类型描述了内存中的电荷是怎么解释的。 对编译器或者解释器而言&#xff0c;类型可以协助确保上面那些电荷、字节在程序的运行中始终如一地被理解。 对程序员而言…

C++算法 —— 递归

一、汉诺塔问题 1.链接 面试题 08.06. 汉诺塔问题 - 力扣&#xff08;LeetCode&#xff09; 2.描述 3.思路 4.参考代码 class Solution { public:void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {dfs(A.size(),A,B,C);}void…

Java项目:基于Springboot+vue社区医院管理系统设计与实现(源码+数据库+毕业论文)

一、项目简介 本项目是一套基于Springbootvue社区医院管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…