InnoDB存储引擎 - 锁引发的问题

我们知道通过锁机制可以使得对共享资源进行并发访问时,能够提供数据的完整性和一致性。实现事务的隔离性要求,可以使得事务可以并发工作。但是锁提高了并发的提示,也引发了一些问题。主要有以下三种:

脏读:在不同的事务下,当前事务可以读到另外事务未提交的数据,即可以读到脏数据
不可重复读:在一个事务内,两次读到的数据不一样
丢失更新:一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致

下面分析一下三种问题。
在讨论事务相关问题时,我们一定要谨记大前提,那就是在各种事务隔离级别下。抛开隔离级别谈事务问题,纯属扯淡。

脏读

在不同的事务下,当前事务可以读到另外事务未提交的数据,即可以读到脏数据。何为脏数据?脏数据是指事务对缓冲池中的行记录的修改,并且还没有提交。脏读违反了事务的隔离性要求。
脏读发生在事务隔离级别是READ UNCOMMITED条件下。而目前绝大多数的数据库的事务隔离级别都至少设置成了READ COMMITED。所以脏读在生产环境中不常发生。

不可重复读

在一个事务A内,我们可能会多次读取同一数据。在这个事务没有提交之前,可能有其他事务B对数据进行了操作,并且提交了。当事务A再次读取这份数据时,发现两次读到的数据是不一致的,这种情况即为不可重复读。

不可重复读和脏读的区别:脏读是读到未提交的数据,违反了数据库事务的隔离性,而不可重复读读到的却是已经提交的数据,违反了数据库事务一致性的要求。

一般来说,不可重复读的问题是可以接受的,因为读到的是已经提交的数据,本身不会带来很大问题。因此,很多数据库厂商(如Oracle、Microsoft SQL Server)将其数据库事务的默认隔离级别设置为READ COMMITED,在这种隔离级别下允许不可重复读的现象。

在InnoDB存储引擎中,默认的隔离级别是RR,通过使用next-key lock算法避免了不可重复读的问题。在next-key lock算法下,对于索引的扫描,不仅是锁住扫描到的索引,而且还锁住这些索引覆盖的范围。因此在这个范围内的插入都是不允许的,这样就避免了其他事务在这个范围内插入数据而导致的不可重复读问题。

举例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

事务A事务B
beginbegin
select * from books.stu;//返回6行
insert into book.stu select 7,‘lujie’;
commit;
select * from books.stu; //返回7行

丢失更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值