通过举例理解sql隔离级别以及事务并发会出现的情况,告别死记硬背
尽量简洁,我们容易记住
即一个事务读取了另一个事务修改但未提交的数据
一个事务中多次读取的结果不一致,主要发生了修改
一个事务中多次读取的结果不一致,主要发生了新增或删除
举例阐述每种隔离级别出现的情况,就能够更深入地理解三种并发情况
见名思义,一个事务可以读到另一个事务修改但未提交的数据
会出现三种情况
事务1
// 1.查看隔离级别 - REPEATABLE READ
SELECT @@GLOBAL.tx_isolation
// 2.设置隔离级别 - READ UNCOMMITTED
set global transaction isolation level READ UNCOMMITTED;
// 5.开启事务
begin;
// 6.查询到修改但未提交的数据,一旦回滚读到的是不被承认的
select * from user where user_id = 1;
// 提交
COMMIT;
事务2
// 3.开启事务
begin;
// 4.修改数据
UPDATE user set user_name = '修改但我要回滚' where user_id = 1;
// 7.回滚数据
ROLLBACK;
事务1读取的结果

事务1
// 3.开启事务
begin;
// 4.第一次查询 -- 修改但要回滚+1
select * from user where user_id = 1;
// 6.第二次查询 -- 修改但要回滚+2
select * from user where user_id = 1;
// 8.第三次查询 -- 原数据
select * from user where user_id = 1;
COMMIT;
事务2
// 1.开启事务
begin;
// 2.第一次修改
UPDATE user set user_name = '修改但要回滚+1' where user_id = 1;
// 5.第二次修改
UPDATE user set user_name = '修改但要回滚+2' where user_id = 1;
// 7.回滚
ROLLBACK;
事务1第一次读取的结果

事务1第二次读取的结果

事务1第三次读取的结果

事务1
// 3.开启事务
begin;
// 4.第一次查询 整个范围的数据
select * from user;
// 6.第二次查询 整个范围的数据
select * from user;
COMMIT;
事务2
// 1.开启事务
begin;
// 2.新增
insert into user values(0,"新增数据")
// 5.回滚
ROLLBACK;
事务1第一次查询结果

事务1第二次查询结果

事务只能读到另一个事务已经提交的数据
会出现以下两种情况
事务1
// 1.查看全局隔离级别 - READ-COMMITTED
SELECT @@GLOBAL.tx_isolation;
// 2.开启事务
begin;
// 5.第一次查询 - 原数据
select * from user where user_id = 1;
// 7.第二次查询 - 张三
select * from user where user_id = 1;
事务2
// 3.开启事务
BEGIN;
// 4.修改但未提交
update user set user_name="张三" where user_id = 1;
// 6.提交
COMMIT;
事务1第一次查询

事务1第二次查询

事务1
// 3.开启事务
begin;
// 4.第一次查询全部的
select * from user ;
// 6.第二次查询全部的
select * from user ;
事务2
// 1.事务开启
BEGIN;
// 2.插入数据
INSERT into user VALUES(0,"迪迦");
// 5.提交
COMMIT;
事务1第一次查询的结果

事务2第二次查询的结果

一个事务多次查询同一个数据,多次读取的结果一致
出现以下幻读情况,避免了不可重复读
事务1
// 1.当前对话的隔离级别-- REPEATABLE-READ
SELECT @@SESSION.tx_isolation
// 2.开启事务
BEGIN;
// 6.第一次查询 -- 原数据
SELECT * from user WHERE user_id = 1;
// 8.第二次查询 -- 原数据
SELECT * from user WHERE user_id = 1;
// 9.提交
COMMIT;
// 10.第三次查询 -- 李四
SELECT * from user WHERE user_id = 1;
事务2
// 3.查看当前会话 -- REPEATABLE-READ
SELECT @@SESSION.tx_isolation
// 4.开启事务
BEGIN;
// 5.修改数据
update user set user_name = "李四" where user_id = 1;
// 7.提交数据
COMMIT;
事务1第一次读取的结果

事务1第二次次读取的结果

事务1提交后,读取的结果,提交后事务就算结束了

事务1
// 3.开启事务
BEGIN;
// 4.第一次查询
SELECT * from user;
// 6.第二次查询
SELECT * from user;
// 7.修改该范围内的名字
update user set user_name = 'xxx'
// 8.第三次查询 -- 多了一条数据
SELECT * from user;
COMMIT;
事务2
// 1.开启事务
BEGIN;
// 2.添加数据
INSERT INTO user VALUES(0,"小黑");
// 5.提交
COMMIT;
事务1第一次查询结果

事务1第二次查询结果,乍一看觉得没有问题

事务1第三次查询结果,结果多了一条数据

两个事务中只要有一个有修改操作,就会发生堵塞,串行读取数据,锁争抢严重
没有所谓幻读问题