MySQL——事务

目录

1.事务简介

2.操作事务

3.事务四大特性ACID

4.并发事务问题

5.事务隔离级别

演示

6.事务原理

[6.1 redo log](#6.1 redo log)

[6.2 undo log](#6.2 undo log)


1.事务简介

事务是一组操作的集合,他是一个不可分割的工作单位,事务把所有的操作作为一个整体一起向系统提交或撤销操作请求,以及这些操作要么同时成功要么同时失败。

默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。

2.操作事务

开启事务

start transaction 或 begin;

提交事务

commit

回滚事务

rollback

3.事务四大特性ACID

  • 原子性
    • 含义:事务是一个不可分割的整体,要么全部执行成功,要么全部失败回滚。就像一个原子,是不可再分的最小单位。
    • 示例 :在银行转账 示例 :在银行转账的事务中,从账户 A 向账户 B 转账 1000 元,这包括从账户 A 扣除 1000 元以及向账户 B 增加 1000 元两个操作。这两个操作必须作为一个整体来执行,要么都成功,要么都不执行。如果只扣除了 A 账户的钱而没有给 B 账户增加,或者相反,就会导致数据不一致,违反了原子性。
  • 一致性
    • 含义:事务执行前后,数据库的完整性约束没有被破坏,数据处于一致的状态。也就是说,事务执行的结果必须使数据库从一个一致性状态转变到另一个一致性状态。
    • 示例:在一个库存管理系统中,当进行商品销售时,不仅要扣除相应商品的库存数量,还要更新销售记录和相关的财务数据等。确保所有相关数据都按照业务规则进行了正确的更新,以保证数据库中数据的一致性,例如库存数量不能为负数,销售金额与商品单价和数量的计算要准确等。
  • 隔离性
    • 含义:多个事务并发执行时,一个事务的执行不能被其他事务干扰,各个事务之间相互隔离,如同在独立的环境中执行一样。
    • 示例:假设有两个用户同时对同一个账户进行操作,一个是查询账户余额,另一个是进行转账操作。隔离性保证了查询操作不会受到转账操作的影响,即查询到的是转账前的准确余额,而转账操作也不会因为查询操作的同时进行而出现数据错误或不一致的情况。
  • 持久性
    • 含义 :一旦事务提交成功,它对数据库所做的修改就会永久保存到数据库中,即使系统出现故障(如断电、系统崩溃等),也能保证数据不会丢失。
    • 示例:用户在电商平台上下单购买商品并完成支付后,订单信息和支付记录等相关数据会被持久化存储在数据库中。即使之后电商平台的服务器出现故障,当系统恢复后,用户的订单和支付信息依然存在,不会因为故障而丢失,保证了数据的持久性。

4.并发事务问题

脏读:一个事务读到另一个事务还没有提交的数据。

不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读

幻读:一个事务按照条件查询时,没有对应的数据行,但是在插入数据时,又发现者行数据存在,好像出现了幻影。

5.事务隔离级别

-- 查看事务隔离级别

select @@transaction_isolation;

-- 设置事务隔离级别

set [session|global](当前表还是全局设置) transaction isolation level [要设置的隔离级别】

演示

1.脏读

在 read uncommited事务隔离级别下

客户端1第一次查询数据

客户端2去修改数据但是未提交

客户端1再次去查询数据两次结果不一样

总结: 在read uncommited事务隔离级别之下,客户端a开启事务去查询数据,客户端b开启事务去修改数据,但是事务还未提交,客户端a再次去查询数据发现两次查询结果不一致出现脏读现象。

所以在read uncommited事务隔离级别之下会出现脏读。

2.不可重复读

在read commited事务隔离级别之下

事务a开启事务查询数据

事务b开启事务去更新数据

事务a再次查询数据,结果一样

事务b提交数据之后事务a去查询

总结 :在read commited事务隔离级别情况下不会出现脏读现象,但是事务a多次查询数据结果不一样,原因事务b开启事务修改数据提交事务了。在read commited事务隔离级别下这就会导致不可重复读。

3.幻读

在repeatatable read事务隔离级别之下

事务a开启事务去查询不存在的数据查不到

事务b去开启数据把事务a查询不到的数据插入表中提交事务

事务a去添加数据结果失败,感觉好像出现幻觉一样我明明查询数据不存在鸭,为啥插入这个不存在的数据为啥失败

总结: 在repeatatable read事务隔离级别下虽然解决了不可重复读现象但是解决不了幻读。就是我明明去查询数据不存在,但是我去插入数据却失败好像出现了幻觉一样

4.串行化serializable

在serializable隔离级别情况下解决了幻读,事务a开启事务之后其他事务只能查询数据不可以修改插入数据会阻塞,等到事务acommited之后才能执行。

注意:事务隔离级别越高,数据越安全,但是性能越低。

6.事务原理

对于事务四大特性是怎么实现的,如何保证原子性,一致性,隔离性,持久性

对于原子性,一致性,持久性都是由InnoDB引擎的两份日志来保证的redolog,undolog

对于隔离性由InnoDB引擎锁机制和MVCC来实现的

6.1 redo log

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。

该日志文件由两部分组成:重做日志缓冲 (redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者是在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中,用于刷新脏页到磁盘,发生错误时,进行数据恢复使用.

没有redo log持久性无法保障

没有redo log

1.当我们去执行update语句会去操作缓冲区,如果缓冲区没有数据把磁盘中的数据读取到缓冲区。

2.操作缓冲区中的数据,缓冲区数据变更,磁盘中没有,这个数据页叫做脏页

3.脏页会在一定时间刷新到磁盘保证数据一致,但是当我们脏页数据往磁盘中刷新的时候出错了。

4.事务都已经提交了,也告诉用户事务提交成功了,但是最终在脏页刷新时候失败了,持久性没有得到保证。

拥有redo log

1.操作缓冲区中的数据会把数据页变化记录在redo log buffer 中

2.在commit的时候会把redo log buffer 中的数据页变化持久化保存到redo log file中

3.隔一段时间脏页刷新到磁盘中出错了可以通过redo log进行恢复

事务操作很多条记录,这些记录都是随机修改我们的数据页,这个时候会涉及到大量磁盘IO,性能比较低。log 日志文件日志文件都是追加的顺序磁盘io,性能要高于随机磁盘io的

这种机制叫做WAL先写日志

6.2 undo log

  • 回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和mvcc(多版本并发控制).
  • undolog和redolog记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undolog中会记录,反之亦然,当update一条记录时,它记录一家对应相反的update记录。当执行rollback时,就可以从undolog中的逻辑记录被取到相应的内容。并进行回滚。
  • undolog销毁:undolog在事务执行时产生,事务提交时,并不会立即删除undolog,因为这些日志可能还用于mvcc
  • undolog存储:undolog采用段的方式进行管理和记录,存放在的面介绍的rollbacksegment 回滚段中,内部包含1024个undologsegment.
相关推荐
chunfeng—6 分钟前
Redis相关命令详解与原理(一)
数据库·redis·缓存
老友@6 分钟前
MySQL + Elasticsearch:为什么要使用ES,使用场景与架构设计详解
数据库·mysql·elasticsearch·搜索引擎·性能优化·系统架构
檀越剑指大厂20 分钟前
【SQL系列】多表关联更新
数据库·sql
♡喜欢做梦1 小时前
【MySQL】联合查询
数据库·mysql
老华带你飞3 小时前
音乐网站|基于SprinBoot+vue的音乐网站(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·音乐网站
gadiaola7 小时前
MySQL从入门到精通(三):MySQL数据类型、SQL语言—DDL
数据库·sql·mysql·database
muxue1788 小时前
关于almalinux分区配置:
linux·运维·数据库
海天胜景10 小时前
Asp.Net Core IIS发布后PUT、DELETE请求错误405
数据库·后端·asp.net
凯子坚持 c10 小时前
【金仓数据库征文】金仓数据库 KES:MySQL 迁移实用指南
数据库·金仓数据库 2025 征文·数据库平替用金仓
小刘|10 小时前
Redis 中简单动态字符串(SDS)的深入解析
数据库·redis·bootstrap