MySQL事务的ACID特性以及并发问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL事务的ACID特性以及并发问题

一、事务概念

InnoDB支持事务,而MyISAM不支持事务

一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个不可分割的单元,只有当事务中的所有操作都正常执行完了,整个事
务才会被提交给数据库
;如果有部分事务处理失败,那么事务就要回退到最初的状态,因此,事务要么全部执行成功,要么全部失败。

所以记住事务的几个基本概念,如下:

  1. 事务是一组SQL语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果。保证事务执行的原子性
  2. 事务的所有SQL语句全部执行成功,才能提交(commit) 事务,把结果写回磁盘
  3. 事务执行过程中,有SQL出现错误,那么事务必须要回滚(rollback) 到最初的状态

比如转账业务需要多条SQL语句共同完成,只有这些SQL都执行成功才算业务成功了

image.png

begin开启事务,如果这2句SQL都成功了,那么commit提交一个事务

如果其中任意一条SQL由于停电,或者服务器出错,导致SQL执行异常,那事务就没有提交,事务会回滚,数据将恢复到事务开始前的状态

这是存储引擎来保证的(redo log和undo log保证的)

image.png

查看当前数据库支持的存储引擎


show engines;

image.png

数据库引擎可以通过命令临时修改,或者通过配置文件永久修改


select @@autocommit;

image.png

@autocommit为1表示事务自动提交,为0表示事务手动提交

做业务的时候,我们一般会在代码上控制这个变量,一般来说,我们的事务由多条SQL组成,所以我们设置为手动提交。业务都成功,则提交这个事务;如果业务中间出现失败,就回滚1个事务

image.png

二、ACID特性

每一个事务必须满足下面的4个特性:

  • 原子性(Atomic):事务是一个不可分割的整体,事务必须具有原子特性。当修改数据时,要么全执行,要么全不执行,即不允许部分事务完成
  • 一致性(Consistency):事务执行之前和执行之后,数据库数据必须保持一致性状态。数据库的一致性状态必须由用户来负责,由并发控制机制实现。拿银行转账来说,只有让一个用户的余额减少,又让一个用户的余额增加才能构成一个完整的事务
  • 隔离性(Isolation):当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到,使得并发执行的各个事务之间不能互相影响。隔离级别:数据的安全性和事务的并发性。隔离越严格,安全性越高,并发性越低(就是并发控制,保证数据安全)
  • 持久性(Durability):事务完成(事务commit成功)以后,DBMS保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据

InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?

  • 持久性是通过 redo log (重做日志)来保证的
  • 原子性是通过 undo log(回滚日志) 来保证的
  • 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的
  • 一致性则是通过持久性+原子性+隔离性来保证

DB写数据都是先在cache缓存上写的(因为速度快),然后操作系统通过磁盘I/O往磁盘上写,当事务成功提交后,commit就返回了。然后cache再慢慢往磁盘上写数据,这个过程中如果由于不可抗因素中断了,导致缓存上的数据向磁盘上写的时候没写完,那此时数据就丢了。系统重启后MySQL数据库会根据redo log来重新执行这个事务并写入缓存,然后写入磁盘,来保证数据库的持久性。由于用户会写很多数据,所以commit不会等着这些数据从缓存全部写到磁盘再返回,因为要经过磁盘I/O,业务上不可能让用户去等那么长时间

MySQL最重要的是日志,不是数据!

事务的ACD特性由redo log和undo log机制保证,事务的I特性由事务的锁机制来保证,锁粒度越大,事务隔离性越好,安全性越高,并发性越低,效率越低

三、事务并发存在的问题

事务处理如果不经隔离,并发执行事务时通常会发生以下问题:

  • 脏读(Dirty Read):一个事务读取了另一个事务未commit的数据(处理了一半的数据) 。例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时如果事务A rollback了,那事务B读到的数据就不是数据库所存放的数-   据了,而是无效的脏数据(脏读必须杜绝,因为事务没有commit;而不可重复读和幻读不一定出问题,因为事务已经commit
  • 不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读取到不同的数据 。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A update操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样(事务B读取了事务A已commit的数据
  • 幻读(Phantom Read):一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如 当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了(事务B读取了事务A新增加的数据或者读不到事务A删除的数据

在有些场景下,不可重复读和幻读一定程度上是可以允许的,不一定非要杜绝(通过设置不同的隔离级别解决),由应用场景需求决定

  • 脏读举例:张三的账户还剩100块,他同时发起两个事务,事务A转账50,事务B购买价格为80的水杯,事务A现对张三的余额减50,然后给另一个人余额加50。由于没有隔离控制,事务B购买水杯前先读取余额,发现只有50,无法购买茶杯,于是茶杯购买失败。此时事务A执行异常,将张三的余额回滚为事务执行前的状态,余额为100。当前场景中事务B读到了事务A还没有commit的数据50,发生了脏读,任何业务场景下都必须杜绝
  • 不可重复读举例:首先事务B查询余额,发现为100。事务A完成转账50,并且commit,事务B再次查询余额,发现变成了50,在某些业务场景下是可以允许的,不一定非要杜绝
  • 幻读举例:事务B查询年龄为20的人,发现有5个。事务A插入或删除了年龄为20的记录,并且commit,事务B再次查询年龄为20的人,发现已经不是5个人了,幻读也是在某些业务场景下是可以允许的,不一定非要杜绝

四、事务相关命令

查看MySQL是否自动提交事务

image.png

1表示自动提交事务,0表示手动提交事务

一般我们业务上如果要考虑到事务处理,我们需要设置为手动提交方式,如果一个事务包含多个SQL,若是自动提交方式,一句SQL执行完就自动提交了,后面的SQL万一执行失败就无法正常rollback,无法保证事务的原子特性

image.png

  • BEGIN:开启一个事务
  • COMMIT:提交一个事务
  • ROLLBACK:回滚一个事务到初始的位置
  • SAVEPOINT point1:设置一个名字为point1的保存点
  • ROLLBACK TO point1:事务只回滚到保存点point1,而不是回滚到初始状态
  • SET TRANSACTION_ISOLATION=‘REPEATABLE-READ’:设置事务的隔离级别
  • SELECT @@TRANSACTION_ISOLATION:查询事务的隔离级别



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
27天前
|
存储 关系型数据库 MySQL
MySQL 8.0特性-自增变量的持久化
【11月更文挑战第8天】在 MySQL 8.0 之前,自增变量(`AUTO_INCREMENT`)的行为在服务器重启后可能会发生变化,导致意外结果。MySQL 8.0 引入了自增变量的持久化特性,将其信息存储在数据字典中,确保重启后的一致性。这提高了开发和管理的稳定性,减少了主键冲突和数据不一致的风险。默认情况下,MySQL 8.0 启用了这一特性,但在升级时需注意行为变化。
|
1月前
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
145 2
|
2月前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
118 43
|
16天前
|
关系型数据库 MySQL
mysql事务特性
原子性:一个事务内的操作统一成功或失败 一致性:事务前后的数据总量不变 隔离性:事务与事务之间相互不影响 持久性:事务一旦提交发生的改变不可逆
|
14天前
|
关系型数据库 MySQL 数据库
MySQL事务隔离级别及默认隔离级别的设置
在数据库系统中,事务隔离级别是一个关键的概念,它决定了事务在并发执行时如何相互隔离。MySQL提供了四种事务隔离级别,每种级别都解决了不同的并发问题。本文将详细介绍这些隔离级别以及MySQL的默认隔离级别。
|
1月前
|
存储 关系型数据库 MySQL
MySQL MVCC深度解析:掌握并发控制的艺术
【10月更文挑战第23天】 在数据库领域,MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种重要的并发控制机制,它允许多个事务并发执行而不产生冲突。MySQL作为广泛使用的数据库系统,其InnoDB存储引擎就采用了MVCC来处理事务。本文将深入探讨MySQL中的MVCC机制,帮助你在面试中自信应对相关问题。
127 3
|
2天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
45 15
|
3天前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
|
7天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
15天前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据