您好,欢迎来到爱够旅游网。
搜索
您的当前位置:首页3.mysql之事务的隔离性详解

3.mysql之事务的隔离性详解

来源:爱够旅游网

事务机制

事务的四个隔离级别

  • 读取未提交的数据
  • 读取已提交的数据
  • 重复读取
  • 序列化

事务选择哪个隔离级别是根据具体的业务场景来使用的,并没有哪个绝对的好坏

读取未提交的数据

比如下面的案例:

修改事务隔离级别:以读取其他事务未提交的数据

  • read uncommitted
  • 会话:Navicat中打开一个查询面板,这个相当于一次会话,关闭这个查询面板就是关闭了这次会话
  • 用法:设置当前会话的隔离级别,隔离级别只是针对当前会话的,不是全局的
set session transaction isolation level read uncommitted

栗子:
打开Navicat,有下面的表:
score:

打开3个查询面板
面板1,A事务修改表中grade为100,但是不提交事务

start transaction;
update score set grade=100;
select * from score;

此时事务内读取到的是修改后的数据

面板2,B事务,不设置隔离级别,直接读取表数据:

start transaction;
select * from score;

这里默认读取的是已提交的数据,这里看到数据并未修改,因为A事务还没有提交

面板3,C事务,设置隔离级别:读取其他事务未提交的数据

set session transaction isolation level read uncommitted;
start transaction;
select * from score;

根据结果可以看到读取的是A事务还未提交的数据

读取已提交数据

比如下面的案例:

  1. 原本的账户中有1000元
  2. 若是A事务给账号添加1000元,此时redo日志中账户金额是2000,
  3. B事务是取出100元,且在A事务未提交前读取未提交的数据,那此时就是1900
  4. 若是A事务因为一些原因最终回滚了,然后B事务又提交了,那此时的1900元的数据就是有问题的
  5. 因此,这种银行业务,读取用户当前账号中的金额绝对不能读取未提交的数据,而是读取已提交的数据

修改事务隔离级别为:只能读取其他事务提交的数据

  • read committed

具体用法:

set session transaction isolation level read committed

栗子:

接着前面的栗子,A事务还未修改,此时打开一个新查询面板,创建C事务,设置读取已提交的数据

set session transaction isolation level read committed;
start transaction;
select * from score;

根据结果,可以看到读取的是已提交的数据,A事务还未提交,修改的数据还未同步:

重复读取

  1. 如果淘宝上一个商品,用户在下单后(还未支付前),商品的价格发生了变化,那么这种情况一般的是更改后的商品价格不会影响更改前已下单的商品价格
  2. 比如说A事务是下单商品,但是这个事务还未提交,此时B事务给商品涨价了,那么不论B事务是否提交,A事务数据的读始终都是下单时的价格(即A事务undo日志中的数据)
  3. 也就是说A事务一旦开启,其他事务进行的操作不会影响到A事务的数据

修改事务的隔离级别:事务在执行中反复读取数据,得到的结果是一致的,不会受其他事务影响

  • repeatable read

具体用法:

set session transaction isolation level repeatable read

栗子:

Navicat中2个面板:

面板1,A事务,读取表中数据:

set session transaction isolation level repeatable read;
start transaction;
select * from score;

面板2,B事务,修改表中数据并提交事务:

start transaction;
update score set grade=100;
select * from score;
commit;

此时表中数据被修改了:

面板1,删除前2条数据,保留一条查询,查看表数据

select * from score;

表中仍然是A事务开始时的数据

事务的序列化

  • 由于事务并发执行所带来的各种问题,前三种隔离级别只使用在某些业务场景中,但是序列化的隔离性,让事务逐一执行,就不会产生上述问题了
  • 这种情况下事务不能并发执行,使用的比较少
set session transaction isolation level serializable

栗子:

Navicat中2个面板

面板1,A事务,会话隔离性设置成序列化

set session transaction isolation level serializable;

面板2,B事务,开启事务后不提交事务:

start transaction;
update score set grade=200;
select * from score;

面板1,查询语句,执行后发现没有出现查询结果,这是因为B事务还未提交,A事务不能执行:

select * from score;

面板2,提交事务后,此时面板1中的查询结果出现了

commit;

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务