MySQL 并发控制

MySQL 并发控制

事务

数据库事务可以保证多个对数据库的操作(也就是 SQL 语句)构成一个逻辑上的整体。构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行

执行了 begin/start transaction 命令后,并不代表事务启动了。只有在执行这个命令后,执行了第一条select 语句,才是事务真正启动的时机;

1
2
3
4
5
6
7
8
9
10
11
# 开启一个事务
START TRANSACTION;

# 多条 SQL 语句
SQL1,SQL2...

# 提交事务
COMMIT;

# 回滚事务
rollback

并发事务带来的问题

脏读、脏写(undo日志回滚了)、丢失修改、不可重复读、幻读

幻读

  1. 开启事务1和事务2
  2. 事务 1 读取数据
  3. 事务 2 插入了新的数据
  4. 事务 2 提交
  5. 事务 1 读取插入的数据但发现读取不到,但如果此时想插入同样的数据,却会提示一个 数据已存在的错误 , 这就叫做幻读
1
2
mysql> insert into p(id,name,age) values(5,"pet",33);
ERROR 1062 (23000): Duplicate entry '5' for key 'p.PRIMARY'

可串行化
增删改 都不行

事务隔离级别

RU、RC、RR、Serializable

隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

默认是 REPEATABLE-READ(可重复读)

可重复读隔离级是由 MVCC(多版本并发控制)实现的,实现的方式是启动事务后,在执行第一个查询语句后,会创建一个 Read View,后续的查询语句利用这个 Read View,通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入了新纪录,是查询不出来这条数据的,所以就很好了避免幻读问题。

1
2
3
4
5
-- 查询事务隔离级别
select @@transaction_isolation;

-- 设置事务隔离级别
set session transaction isolation level read committed;

MySQL 并发控制
https://cs-lb.github.io/2024/11/03/Java/MySQL-并发控制/
作者
Liu Bo
发布于
2024年11月3日
许可协议