事务的特性、隔离级别、不同的隔离级别有什么问题、什么是幻读
事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账 1000 元,这个转账会涉及到两个关键操作就是:将小明的余额减少 1000 元,将小红的余额增加 1000 元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。
不可重复度和幻读区别:不可重复读的重点是修改,幻读的重点在于新增或者删除
例 1(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务 1 中的 A 先生读取自己的工资为 1000 的操作还没完成,事务 2 中的 B 先生就修改了 A 的工资为 2000,导致 A 再读自己的工资时工资变为 2000;这就是不可重复读
例 2(同样的条件, 第 1 次和第 2 次读出来的记录数不一样 ):假某工资单表中工资大于 3000 的有 4 人,事务 1 读取了所有工资大于 3000 的人,共查到 4 条记录,这时事务 2 又插入了一条工资大于 3000 的记录,事务 1 再次读取时查到的记录就变为了 5 条,这样就导致了幻读
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ-UNCOMMITTED | √ | √ | √ |
| READ-COMMITTED | × | √ | √ |
| REPEATABLE-READ | × | × | √ |
| SERIALIZABLE | × | × | × |
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过 SELECT @@tx_isolation;命令来查看,MySQL 8.0 该命令改为 SELECT @@transaction_isolation;
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
在下面我会使用 2 个命令行 MySQL,模拟多线程(多事务)对同一份数据的脏读问题。
MySQL 命令行的默认配置中事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。如果要显式地开启一个事务需要使用命令:START TRANSACTION。
我们可以通过下面的命令来设置隔离级别
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
我们再来看一下我们在下面实际操作中使用到的一些并发控制语句:
START TRANSACTION |BEGIN:显式地开启一个事务COMMIT:提交事务,使得对数据库做的所有修改成为永久性ROLLBACK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改

还是刚才上面的读已提交的图,虽然避免了读未提交,但是却出现了,一个事务还没有结束,就发生了不可重复读问题


SQL脚本 1 在第一次查询工资为 500 的记录时只有一条,SQL脚本 2 插入了一条工资为 500 的记录,提交之后;SQL脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读
转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916 如果觉得本文对您有帮助,请点击赞支持一下,您的支持是我写作最大的动力,谢谢。