mysql事务隔离级别

事务的并发带来了什么问题

  • 脏读

当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

例子:

1. 张三初始工资1000元,人事修改为2000 但是未提交
2. 张三读取工资 发现修改为2000 
3. 人事发现修改错误,回滚了提交。张三再读发现变成了1000

张三读到的2000就是脏数据

  • 幻读

指事务不独立执行时发生的现象,表现为新增删除的时候。 事务A操作所有数据,变更了所有行的数据。然后事务B新增了一条数据,A事务读数据发现了一条未被修改的数据,好像出现了幻觉

例子:

1. 公司所有人工资统一为1000元。事务A为每人加了100 变为1100
2. 事务B 人事新增一名员工,工资为1000元。
3. 事务A 再次读取发现还有一个人的工资没更新 而且人也多了一个

如果能避免在事务提交前 禁止添加新数据,则能避免出现该问题

  • 不可重复读

在事务A中先读取一个值,然后事务B更新了此值,事务A中在读这个值就会变得不一致,同一个事务中前后读一个值返回的不一致

例子:

1. 张三初始工资为1000 事务A中 张三读取到1000
2. 事务B 人事修改为2000 提交。
3. 事务A 再次读取工资发现变成了2000,前后数据不一致

不可重复读:同一事务中前后读取数据不一致 重点在于修改,幻读在于新增和删除

为了解决上面的问题,mysql提出了四种隔离级别


事务隔离级别
  • read uncommitter 未提交读
  • read committer 提交读
  • repeatable read 可重复读
  • serializable 串行化

下面模拟集中情况来解释说明集中级别

CREATE TABLE `test` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `account` float DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
insert into test (account) values(1000);
insert into test (account) values(1000);

Read uncommitter

打开两个会话 会话1中执行

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
select * from test;

结果为:

在这里插入图片描述

会话2中执行 未提交事务

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
UPDATE test SET account = 1200 WHERE id = 1;

会话1中执行

select * from test 

结果:

结论

read uncommitter 为最低的事务隔离级别。即使其他事务未提交也能读取到脏数据,但是读到的数据可能没有真正的发生改变,因为只有事务commit后才会提交到数据库

Read committer

打开两个会话 会话1中执行

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
select * from test;

结果为:

会话2中执行 未提交事务

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
UPDATE test SET account = 1200 WHERE id = 1;

会话1中执行

select * from test 

结果

在这里插入图片描述

会话2中执行

commit

会话1中执行

select * from test 

结果

结论

read committer 不会读取到其他未提交事务的数据,可以避免脏读,但是同一事务1条数据可能有多个值

repeatable read

打开两个会话 会话1中执行

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

结果为:

会话2中执行 未提交事务

set session transaction isolation level repeatable read;
start transaction;
UPDATE test SET account = 1200 WHERE id = 1;

会话1中执行

select * from test 

结果

在这里插入图片描述

会话2中执行

commit

会话1中执行

select * from test 

结果
在这里插入图片描述

会话1执行

commit;
select * from test 
insert into test (id,account) value(3,1000);

结果 会插入失败
在这里插入图片描述

结论

repeatable Read 可以可重复读 同一事务多次读取数据不会变,但是如果外部确实已经更新或者添加,会出错或者更改。

Serializable

将事务等级开启到最高,会串行化执行,所有其他的事务等待挂起。
如果超时(这个时间可以进行配置),会出现Lock wait time out提示

结论

当我们将当前会话的隔离级别设置为serializable的时候,其他会话对该表的写操作将被挂起。可以看到,这是隔离级别中最严格的,但是这样做势必对性能造成影响。所以在实际的选用上,我们要根据当前具体的情况选用合适的隔离级别。

小结
事务隔离级别脏读不可重复读幻读
read uncommittor可能可能可能
read committor不可能可能可能
repeatable read不可能不可能innodb不可能
serializable不可能不可能不可能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值