mysql学习-事务隔离级别

发布于:2025-04-02 ⋅ 阅读:(62) ⋅ 点赞:(0)

1、事务概述

用户定义的一些列操作,将多个sql语句视为一个整体去执行,这些语句要么全部执行成功了,要么全部不执行。事务对于保证数据的一致性和完整性至关重要,尤其在多个用户对数据库进行并发操作。如果只有一个客户端连接操作mysql,就没必要讨论事务了。

2、如何告诉mysql是事务语句

begin/commit(begin和commit之间的语句,被视为事务)
begin/rollback(begin和rollback之间的语句,被视为回滚事务)

2、MySQL支持四种标准的事务隔离级别

2.1、read uncommit(读未提交)

最低隔离级别,允许一个事务读取其他事务未提交的数据。这会导致脏读、不可重复读、幻读问题。

设置隔离级别sql语句:

set transaction isolation level read uncommitted;

脏读

右侧客户端开启事务,插入数据,但未commit;
左侧客户端开启事务,却能读到右侧客户端未提交的事务数据;
相当于一个mysql客户端,读取到另一个客户端事务执行中间的结果。

【解决脏读】

可以升级隔离级别到read commit

2.2、read commit(读已提交)

一个事务只能读取其他事务已经提交的数据,可以防止脏读,但无法避免不可重复读和幻读

设置隔离级别sql语句:

set transaction isolation level read committed;

不可重复读

右侧客户端开启事务,2次查询name为test1的age,是不一样的结果。
相当于在一个事务内,查询某个值,俩次结果不同,不符合预期。
原因:第二次读取的时候,读到了其他事务提交的结果。

【解决不可重复读】

可以升级隔离级别到 repeatable read

2.3、repeatable read(可重复读,mysql的默认级别)

这是MySQL的InnoDB存储引擎默认的隔离级别。它确保在同一事务内的多次读取同样的数据行时,即使其他事务修改了这些数据行,也不会影响当前事务的读取结果。这可以防止脏读和不可重复读,但幻读仍可能发生。

幻读

右侧客户端开启事务,先查询了下id>4的数据,然后插入一条新数据,但是报错了。
原因:左侧客户端开启事务,并且已经插入了这条新数据commit;
所以会出现,右侧客户端以为可以插入新数据,但是插入数据又报错了。

[解决办法]

给读操作加锁(for update),右侧客户端会阻塞等待左侧客户端事务完成。

select * from student_info where id > 4 for update;

2.4、serializable(可串行化)

最高的隔离级别,完全串行化处理,事务一个接一个地执行,可以防止所有并发引起的问题,包括脏读、不可重复读和幻读,这个效率也是最低的。

学习链接:https://github.com/0voice


网站公告

今日签到

点亮在社区的每一天
去签到