一文带你了解MySQL的事务



在这里插入图片描述

欢迎来到 请回答1024 的博客

🍎🍎🍎欢迎来到 请回答1024的博客

关于博主: 我是 请回答1024,一个追求数学与计算的边界、时间与空间的平衡,0与1的延伸的后端开发者。

博客特色: 在我的博客中,开设了如下专栏(点击可以进入专栏奥~): JavaMySQLRedisSpringSpringBootSpringCloudRabbitMQ微服务分布式 等相关技术专栏。期待与您一起,探索编程世界中的发现和创新之旅。

🌈我的主页 : https://reply1024.blog.csdn.net

敬请期待定期更新、见解和教程!让我们一起踏上这段编码冒险之旅!

数学与计算的边界 时间与空间的平衡 0与1的延伸

☃️概述

事务是逻辑上一组操作的集合,事务会把所有操作作为一个整体一起向系统 提交 或 撤销 操作请求,即这些操作要么同时成功,要么同时失败。

☃️事务演示

❄️❄️基本操作

-- 1. 查询张三账户余额
select * from account where name = '张三';
-- 2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
-- 此语句出错后张三钱减少但是李四钱没有增加
模拟sql语句错误
-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';

-- 查看事务提交方式
SELECT @@AUTOCOMMIT;
-- 设置事务提交方式,1为自动提交,0为手动提交,该设置只对当前会话有效
SET @@AUTOCOMMIT = 0;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;

-- 设置手动提交后上面代码改为:
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
commit;

❄️❄️操作方式二

开启事务:
START TRANSACTION 或 BEGIN TRANSACTION;
提交事务:
COMMIT;
回滚事务:
ROLLBACK;
操作实例:

start transaction;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
commit;

☃️四大特性ACID

● 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败
● 一致性(Consistency):事务完成时,必须使所有数据都保持一致状态
● 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
● 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的


☃️并发事务存在的问题

问题 描述
脏读 一个事务读到另一个事务还没提交的数据
不可重复读 一个事务先后读取同一条记录,但两次读取的数据不同(侧重内容数据的修改)
幻读 一个事务按照条件查询数据时,没有对应的数据行,但是再插入数据时,又发现这行数据已经存在(侧重新增或删除,插入数据读到多了一行)

不可重复读:破坏了一致性,update 和 delete 幻读:破坏了一致性 insert

不可重复读和幻读的区别
不可重复读 的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改;
幻读 的重点在于记录新增比如多次执行同一条查询语句(DQL)时,发现查到的记录增加了。 幻读其实可以看作是不可重复读的一种特殊情况,
单独把区分幻读的原因主要是解决幻读和不可重复读的方案不一样。

举个例子:执行 delete 和 update 操作的时候,可以直接对记录加锁,保证事务安全。 而执行 insert
操作的时候,由于记录锁(Record Lock)只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁(Gap Lock)。
也就是说执行 insert 操作的时候需要依赖 Next-Key Lock(Record Lock+Gap Lock)
进行加锁来保证不出现幻读。

这三个问题的详细演示https://www.bilibili.com/video/BV1Kr4y1i7ru?p=55cd


☃️并发事务隔离级别

读未提交:原理:直接读取数据,不能解决任何并发问题

读已提交:读操作不加锁,写操作加排他锁,解决了脏读。原理:利用MVCC实现,每一句语句执行前都会生成Read View(一致性视图)

可重复读:MVCC实现,只有事务开始时会创建Read View,之后事务里的其他查询都用这个Read View。解决了脏读、不可重复读,快照读(普通查询,读取历史数据)使用MVCC解决了幻读,当前读(读取最新提交数据)通过间隙锁解决幻读(lock in share mode、for update、update、detete、insert),间隙锁在可重复读下才生效。(默认隔离级别)

可串行化:原理:使用锁,读加共享锁,写加排他锁,串行执行

总结: 读已提交和可重复读实现原理就是MVCC Read View不同的生成时机。 可重复读只在事务开始时生成一个Read
View,之后都用的这个;读已提交每次执行前都会生成Read View。

MySQL 在 InnoDB下是默认可重复读的隔离级别,加上 MVCC机制 解决了脏读、不可重复读、幻读的问题。

在这里插入图片描述

● √ 表示在当前隔离级别下该问题会出现 ● Serializable 性能最低;Read uncommitted 性能最高,数据安全性最差
● 在 MySQL 的 InnoDB 引擎下,Repeatable Read 其实不会发生幻读(MVCC机制)。 ● 自 MySQL5.5
之后,默认的存储引擎是 Innodb。

查看事务隔离级别:
SELECT @@TRANSACTION_ISOLATION;
设置事务隔离级别:
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效

☃️实现事务的原理

MySQL 中的 ACID 实现原理:
原子性undolog(记录事务开始前的老版本数据,可以保证原子操作,回滚,实现MVCC版本链)
隔离性读写锁MVCC
持久性redo log(记录事务开启后对数据的修改,可用于crash-safe)


在这里插入图片描述



相关推荐

  1. 了解状态机思维

    2024-05-01 14:24:02       63 阅读
  2. 了解机器学习算法

    2024-05-01 14:24:02       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-01 14:24:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-01 14:24:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-01 14:24:02       82 阅读
  4. Python语言-面向对象

    2024-05-01 14:24:02       91 阅读

热门阅读

  1. 在windows中安装flask虚拟环境步骤

    2024-05-01 14:24:02       33 阅读
  2. Linux从入门到精通

    2024-05-01 14:24:02       26 阅读
  3. 2024年华东杯数学建模思路+论文+代码

    2024-05-01 14:24:02       29 阅读
  4. Spring Boot微服务架构实战

    2024-05-01 14:24:02       32 阅读