MySQL事务基本使用
1 事务概述
1.1 事务的支持情况
使用SHOW ENGINES
命令来查看当前MySQL支持的存储引擎,以及这些存储引擎是否支持事务
能看出在 MySQL 中,只有InnoDB 是支持事务的。
1.2 事务的特性
ACID
- 原子性(A)
⼀个事务的所有操作,要么全部完成,要么都没完成,不能结束在中间环节。如果事务在执⾏过程中发⽣错误,会被回滚到事务开始之前的状态
- 一致性(C)
在事务开始之前以及事务结束之后,数据库的完整性不能被破坏
- 隔离性(I)
允许多个并发事务同时对数据进⾏修改和读写的能⼒,它可以防⽌由于多个事务并发执⾏时由于交叉执⾏⽽导致的数据不⼀致
- 持久性(D)
事务处理结束了以后,对数据的修改是永久的,即使是发⽣了系统故障,数据也不会丢失
1.3 事务的状态
2 使用事务
使用事务有两种方式,分别为 显式事务 和 隐式事务 。
2.1 显示事务
START TRANSACTION
或者BEGIN
,作用是显式开启一个事务
mysql> BEGIN; #或者 mysql> START TRANSACTION;
START TRANSACTION
语句相较于 BEGIN
特别之处在于,后边能跟随几个 修饰符 :
① READ ONLY
:标识当前事务是一个 只读事务 ,也就是属于该事务的数据库操作只能读取数据,而不能修改数据。
② READ WRITE
:标识当前事务是一个 读写事务 ,也就是属于该事务的数据库操作既可以读取数据,也可以修改数据。
③ WITH CONSISTENT SNAPSHOT
:启动一致性读。
- 一系列事务中的操作(主要是DML,不含DDL)
- 提交事务 或 中止事务(即回滚事务)
# 提交事务。当提交事务后,对数据库的修改是永久性的。 mysql> COMMIT; # 回滚事务。即撤销正在进行的所有没有提交的修改 mysql> ROLLBACK; # 将事务回滚到某个保存点。 mysql> ROLLBACK TO [SAVEPOINT]
2.2 隐藏事务
MySQL中有一个系统变量 autocommit :
mysql> SHOW VARIABLES LIKE 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set (0.01 sec)
-
当我们设置 autocommit=0 时,不论是否采用
START TRANSACTION
或者BEGIN
的方式来开启事务,都需要用COMMIT
进行提交,让事务生效,使用ROLLBACK
对事务进行回滚。 -
当我们设置 autocommit=1 时,每条 SQL 语句都会自动进行提交。 不过这时,如果你采用
START TRANSACTION
或者BEGIN
的方式来显式地开启事务,那么这个事务只有在COMMIT
时才会生效,在ROLLBACK
时才会回滚。
3 事务隔离等级
3.1 数据并发问题
1. 脏写( Dirty Write )
对于两个事务 Session A、Session B,如果事务Session A 修改了 另一个 未提交 事务Session B 修改过 的数据,那就意味着发生了 脏写
2. 脏读( Dirty Read )
对于两个事务 Session A、Session B,Session A 读取 了已经被 Session B 更新 但还 没有被提交 的字段。之后若 Session B 回滚 ,Session A 读取 的内容就是 临时且无效 的。
3. 不可重复读( Non-Repeatable Read )
对于两个事务Session A、Session B,Session A 读取 了一个字段,然后 Session B 更新 了该字段。 之后Session A 再次读取 同一个字段, 值就不同 了。那就意味着发生了不可重复读。
4. 幻读( Phantom )
对于两个事务Session A、Session B, Session A 从一个表中 读取 了一个字段, 然后 Session B 在该表中 插 入 了一些新的行。 之后, 如果 Session A 再次读取 同一个表, 就会多出几行。那就意味着发生了幻读。
3.2 事务隔离等级介绍
上面介绍了几种并发事务执行过程中可能遇到的一些问题,这些问题有轻重缓急之分,我们给这些问题按照严重性来排一下序:
脏写 > 脏读 > 不可重复读 > 幻读
我们愿意舍弃一部分隔离性来换取一部分性能在这里就体现在:设立一些隔离级别,隔离级别越低,并发问题发生的就越多。 SQL标准 中设立了4个 隔离级别 :
果。不能避免脏读、不可重复读、幻读。
- READ UNCOMMITTED :读未提交,在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。不能避免脏读、不可重复读、幻读。
- READ COMMITTED :读已提交,它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。可以避免脏读,但不可重复读、幻读问题仍然存在。
- REPEATABLE READ :可重复读,事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。可以避免脏读、不可重复读,但幻读问题仍然存在。这是MySQL的默认隔离级别。
- SERIALIZABLE :可串行化,确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下。能避免脏读、不可重复读和幻读。
3.3 设置事务隔离等级
MySQL的默认隔离级别为REPEATABLE READ
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔离级别; #其中,隔离级别格式: > READ UNCOMMITTED > READ COMMITTED > REPEATABLE READ > SERIALIZABLE
4 小结
数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!