外观
说一下 MySQL 隔离级别,默认是哪个
读未提交(READ UNCOMMITTED
)
- 定义:在该隔离级别下,一个事务可以读取到另一个未提交事务修改的数据,这是最低的隔离级别,几乎没有提供任何数据一致性的保证。
- 可能出现的问题:会产生脏读(
Dirty Read
)问题,即一个事务读取到了另一个事务未提交的数据,如果另一个事务回滚,那么读取到的数据就是无效的。 - 示例:
-- 设置隔离级别为读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
-- 事务A读取数据
SELECT * FROM table_name;
读已提交(READ COMMITTED
)
- 定义:一个事务只能读取到其他事务已经提交的数据,避免了脏读问题。
- 可能出现的问题:会出现不可重复读(
Non - Repeatable Read
)问题,即在一个事务内,多次读取同一数据可能会得到不同的结果,因为在两次读取之间可能有其他事务对该数据进行了修改并提交。 - 示例:
-- 设置隔离级别为读已提交
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
-- 事务A第一次读取数据
SELECT * FROM table_name;
-- 其他事务修改并提交数据
-- 事务A第二次读取数据
SELECT * FROM table_name;
可重复读(REPEATABLE READ
)
- 定义:在同一个事务中,多次读取同一数据始终保持一致,不会受到其他事务修改的影响。
MySQL
的可重复读隔离级别通过MVCC
(多版本并发控制)来实现,保证了事务在执行期间看到的数据是一致的。 - 可能出现的问题:会出现幻读(
Phantom Read
)问题,即一个事务在执行过程中,当按照某个条件查询数据时,前后两次查询得到的结果集行数不同,因为在两次查询之间可能有其他事务插入或删除了符合条件的数据。不过,MySQL
的InnoDB
存储引擎通过间隙锁(Gap Lock
)在一定程度上解决了幻读问题。 - 示例:
-- 设置隔离级别为可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
-- 事务A第一次查询符合条件的数据
SELECT * FROM table_name WHERE condition;
-- 其他事务插入或删除符合条件的数据并提交
-- 事务A第二次查询符合条件的数据
SELECT * FROM table_name WHERE condition;
串行化(SERIALIZABLE
)
- 定义:这是最高的隔离级别,事务之间是串行执行的,即一个事务执行时,其他事务必须等待,避免了脏读、不可重复读和幻读问题。
- 特点:这种隔离级别保证了数据的强一致性,但会严重影响并发性能,因为事务需要排队执行,在高并发场景下会导致性能下降。
- 示例:
-- 设置隔离级别为串行化
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
-- 事务A执行操作
SELECT * FROM table_name;