Mysql:事务

embedded/2024/9/21 11:19:45/

事务

  • 一、概念和特性
  • 二、事务是如何实现的?
    • <一>、原子性(undo log)
    • <二>、持久性(redo log)
    • <三>、隔离性(mvcc + lock)
    • <四>、一致性(constraint)

一、概念和特性

1、何为事务

  • 事务是指逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全都失败

2、事务的四大特性(ACID)

  • 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
  • 一致性(Consistency):事务执行的结果必须使数据库从一个一致性状态到另一个一致性状态
  • 隔离性(Isolation):多个并发用户访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离,隔离性由隔离级别保障
  • 持久性(Durability):一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

3、事务并发问题

  • 脏读:一个事务读到了另一个事务未提交的数据
  • 不可重复读:一个事务读到了另一个事务已经提交的数据。引发事务中的多次查询结果不一致
  • 幻读:一个事务读到了另一个事务已经插入的数据。导致事务中多次查询的结果不一致

4、事务隔离级别

  • read uncommitted 读未提交:一个事务读到另一个事务没有提交的数据。产生问题:脏读、不可重复读、幻读
  • read committed 读已提交:一个事务读到另一个事务已经提交的数据。产生问题:不可重复度、幻读
  • repeatable read 可重复读:在一个事务中读到的数据始终保持一致,无论另一个事务是否提交。
  • serializable 串行化:同时只能执行一个事务。

二、事务是如何实现的?

<一>、原子性(undo log)

  • 原子性的实现主要是靠数据库中的回滚机制,回滚则是通过undo log实现的,所以undo log也称为回滚日志
  • undo log能够保证事务在回滚时,能够撤销所有执行成功的Sql
  • undo log是逻辑日志,记录的是sql相关的信息,比如在执行insert时,undo log记录的是delete语句;反之执行delete语句的时候,undo log保留的是insert

<二>、持久性(redo log)

1、redo log

  • Mysql最终的数据都是存在磁盘中的,但对mysql的操作如果都是读写磁盘的话,就太慢了,所以mysql提供了buffer pool,buffer pool包含了磁盘中部分数据页的映射
  • mysql读取数据时,会先从buffer pool读取数据,如果没有,则从磁盘中读到buffer pool中
  • 当向mysql写入数据时,会先写到buffer pool中,buffer pool更新的数据会定期刷新到磁盘中(此过程称为刷脏),如果在刷脏的过程中,mysql突然出现宕机,就会导致出现数据丢失
  • redo log就是解决这个问题,采用预写的方式记录日志,先记录日志,再刷数据到buffer pool,这样在mysql出现宕机时,可以从磁盘中读取redo log进行数据的恢复,从而保证了数据的持久性
  • redo log最主要的作用就是用于数据库异常宕机的恢复工作,假如数据库永远不会发生异常宕机,那么根本不需要redo log,因为InnoDB有线程不断的把做把脏页刷新到磁盘的工作,数据库如果一直不宕机,就不会有问题

2、binlog
与redo log常用来比较的是binlog,binlog主要是用来做备份的,下面是它们的一些区别

  • redo log是innoDB存储引擎特有的;binlog是server层,属于共有的
  • redo log是物理日志,记录某个数据页的修改;binlog是逻辑日志(记录DML语句)
  • redo log是一个环,循环写;binlog是追加写,不会覆盖以前的日志
  • redo log用于异常重启;binlog用于备份
  • binlog以事件的形式记录了所有的DML和DDL语句(因为它记录的是操作而不是数据值,属于逻辑日志),可以用来做主从复制和数据恢复

<三>、隔离性(mvcc + lock)

  • 原子性和持久性都是基于单个事务内部的措施,而隔离性是多个事务相互隔离、互不影响的特性
  • 事务间的写操作主要是通过锁来实现的,但如果读也加锁的话就会极大地降低并发所以产生了MVCC机制

1、MVCC

  • 全称:MutilVersion concurrency control,多版本并发控制,核心思想是读不加锁,读写不冲突
  • MVCC实现原理是数据快照,不同事务访问不同版本的数据快照。

首先不同版本的数据快照是由undo log实现的

  • Innodb下的表有默认字段和可见字段,默认字段有隐藏的列,默认字段最关键的两个列,一个保存了行的事务id,一个保存了行的回滚指针,如下所示
insert into user (id,name,age,sex)  values (1,'李世民','2000','男');
trx_idroll_pointeridnameagesex
rowid1NULL1李世民2000
执行update语句
update user set name = '武则天',sex = '女' where id = 1;
  • –最新版本
trx_idroll_pointeridnameagesex
rowid2aaaa1武则天2000
  • –上个版本,上面那个版本的回滚指针就是指的下面这条的地址
trx_idroll_pointeridnameagesex
rowid1NULL1李世民2000

其次,当前事务能看到哪个版本的数据快照是由readview实现的

  • 对于读未提交隔离级别来说,直接读取最新版本记录就好了,不需要读取快照版本
  • 对于串行化隔离级别来说,读写都加锁,也不需要快照版本
  • 对于读已提交和可重复读隔离级别来说,就需要undo log中的版本链

2、MVCC中的读操作

  • MVCC中的读不加锁是相对的,快照读不会加锁,同时还会根据隔离级别来判断会不会加锁,串行化读写都会加锁

快照读:普通的select操作

select * from table where ?

快照读就是通过MVCC实现的,访问可见版本的数据

当前读:特殊的读操作,插入/更新/删除操作,需要加锁

update table set ? where ?;
insert into table values ();
delete table where ?;
select * from table where ? lock in share mode;
select * from table where ? for update;

为什么当前读需要加锁?
数据库中的insert/update/delete操作都是伴随着读取数据的,且必须是当前最新数据,所以称为当前读
当一条update语句发送给Mysql后,Mysql server会根据where条件,读取第一条满足条件的记录,然后innodb引擎调用读取数据接口,返回这条记录,并加锁,会再发起一条update请求,更新这条记录,因此update操作内部包含了一个当前读,同理,delete操作也是如此,insert稍微有些不同,简单来说,insert的时候会触发unique key的冲突检查,也会进行一个当前读

<四>、一致性(constraint)

  • 一致性主要是指事务前后数据的完整性没有被破坏
  • 可以通过主键、外键、唯一约束、非空约束等来完成,如果有事务破坏这些约束,就不可以进行提交
  • 此外原子性、持久性、一致性都是为了保证最终的一致性

http://www.ppmy.cn/embedded/25884.html

相关文章

嵌入式学习——C语言基础——day13

1. 结构体类型的定义 struct 类型名 { 数据类型1 成员变量1; 数据类型2 成员变量2; 数据类型3 成员变量3; ... }; 定义结构体中可以使用的数据类型有 1.基本数据类型&#xff1a;int long short char doub…

knife4j swagger 使用笔记

1.接口访问的端口跟后台设置的不一致&#xff0c;接口请求无反应 处理办法 2.响应参数不显示问题 &#xff08;1&#xff09;返回的参数里面一定要有响应的参数对象&#xff0c;如下&#xff1a; &#xff08;2&#xff09;TableDataInfo 定义成泛型类 TableDataInfo package…

前端开发者如何在项目里控制修改组件的样式

1为了让自己快速下班&#xff0c;修改样式应该是占据大部分时间&#xff0c;在很多组件库的项目里&#xff0c;都会提到主题设置。 比如element的scss配置变量&#xff0c;通常有人喜欢直接引入css样式来快速完成任务&#xff0c;然后在全局覆盖这些选择器对应的样式&#xff0…

Nacos和Eureka有什么区别!!!

一致性模型&#xff1a; Eureka&#xff1a;采用的是 AP&#xff08;Availability, Partition Tolerance&#xff09;模型&#xff0c;即在面临网络分区或部分节点故障时优先保证系统的可用性&#xff0c;牺牲一定的数据一致性。Eureka 通过自我保护机制&#xff0c;允许在节点…

【MySQL】A01、性能优化-参数监控分析

1、参数监控 1.1、MySQL command 查看 mysql>SHOW STATUS; &#xff08;服务器状态变量&#xff0c;运行服务器的统计和状态指标&#xff09; mysql> SHOW VARIABLES;&#xff08;服务器系统变量&#xff0c;实际上使用的变量的值&#xff09; mysql> SHOW STATUS …

Microsoft Edge 使用心得与深度探索

Microsoft Edge 是微软推出的一款基于 Chromium 开源项目的网页浏览器&#xff0c;它继承了 Chrome 的许多特性&#xff0c;并添加了一些独特的功能&#xff0c;比如垂直标签页、集锦、沉浸式阅读器等。 Microsoft Edge 使用心得与深度探索 一、Microsoft Edge 简介 Microsof…

容器的通俗讲解

想象一下&#xff0c;你正在厨房准备做一顿美味的大餐。厨房里有各种各样的厨具和食材&#xff0c;但是有时候&#xff0c;为了做一道特别的菜&#xff0c;你需要把一些特定的材料和工具单独放在一起&#xff0c;不让它们和其他菜肴的用品混在一起&#xff0c;这样既能保证这道…

【动态规划】Leetcode 32. 最长有效括号【困难】

最长有效括号 给你一个只包含 ‘(’ 和 ‘)’ 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 2&#xff1a; 输入&#xff1a;s “)()())” 输出&#xff1a;4 解释&#xff1a;最长有效括号子串是 “()()” 解题思路 1…