总览

MySQL事务隔离级别

read uncommitted 读取未提交的数据

read committed 读取提交的数据

repeatable read 可重复读

serializable 串行化

常见问题

更新丢失————事务A的操作被事务B覆盖

脏读————事务A读取了事务B已经修改但尚未提交的数据,若事务B回滚,则事务A读取到的数据为脏数据

不可重复读————事务A执行操作时两次读取数据不一致

幻读————再解决不可重复读问题的基础上,可能无法根据查询到的值进行修改表数据。例如事务A无法插入一条自己事务内查询不到但事务B已经插入的相同数据,原因是事务B在事务A开始之后进行的插入...

MySQL相关操作
MySQL之后隔离级别的关键字为transaction_isolation
MySQL8之前隔离级别的关键为tx_isolation
隔离级别的作用范围有GLOBAL和SESSION
查看隔离级别
show [GLOBAL|SESSION] VARIABLES like 'transaction_isolation'
SElECT @@transation_isolation
设置隔离级别
SET [SESSION|GLOBAL] transaction_isolation=[0|1|2|3]
read uncommitted

此隔离级别中,所有事务都可以看到其他未提交事务的执行结果。(很少使用,舍弃了所有安全性的同时并没有明显性能提升)

问题:出现脏数据

read committed

此隔离级别中,一个事务只能看见已提交事务所做的改变。

问题:不可重复读

repeatable read

MySQL默认的事务隔离级别

此隔离级别可以确保同一事务内相同的查询语句执行结果一致

问题:幻读

实例:
-- 事务一
BEGIN;
SELECT * FROM table00;
/*
查询结果:
|id|name|
|-|-|
|1|wu|
*/
-- 此时系统遇到并发,首先执行完事务二
INSERT INTO table00 VALUES(2,"we"); -- 执行失败
SELECT * FROM table00;
/*

查询结果不变:(可重复读但出现幻觉——明明不存在却无法插入)

|id|name|
|-|-|
|1|wu|
*/
COMMIT;
-- 事务二
BEGIN;
SELECT * FROM table00;
/*
查询结果:
|id|name|
|-|-|
|1|wu|
*/
INSERT INTO table00 VALUES(2,"we"); -- 插入
SELECT * FROM table00;
/*
查询结果: (成功插入)
|id|name|
|-|-|
|1|wu|
|2|we|
*/
COMMIT;

避免幻读

乐观锁为理论基础的MVCC(多版本并发控制)

间隙锁

serializable

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突。换言之,它会在每条select语句后自动加上lock in share mode,为每个查询操作施加一个共享锁。在这个级别,可能导致大量的锁等待现象。该隔离级别主要用于InnoDB存储引擎的分布式事务。

隔离级别的选择(注意这部分是纸上谈兵,算是学习到现在的个人见解和猜测吧)

并发量很少的情况下可以考虑选择串行化级别,一般来说面向用户尽可能不用此隔离级别。

接着就是使用用户体验较好的乐观锁

在高并发情况下增加消息队列对大量请求进行处理