这是一道经典的程序员面试题,在Mysql中,如果有多个事务同时访问同一行数据,那么需要加锁么?我们都知道,在Mysql中有行锁,如果有多个事务同时修改同一行数据,那么需要加锁来防止并发问题。那么,如果有事务修改数据,又有事务读取这个数据,需要加锁么?
答案是不一定,事实上,Mysql的很多数据库引擎为了提升并发性能,都做了多版本并发控制,也就是我们常说的MVCC,事实上,除了Mysql,其他知名的关系型数据库,例如Oracle,PostgreSql也实现了多版本并发控制,尽管实现方式各不相同,但是他们的本质为了实现非阻塞读,也就是即便是这一行数据在做变更的时候,也能被读取到。
那么,Mysql是如何实现MVCC的呢?在Mysql的每一行数据中,除了我们定义的数据列,还有2个隐藏的列,一个是数据的变更时间,一个是这行数据的删除时间,当然,这个时间并不是简单的时间戳,而是一个严格递增的系统版本号。
当InnoDB发生Insert事件的时候,会插入当前行并且以取得的系统版本号作为数据版本号。
当InnoDB发生Delete时间的时候,不会删除当前行,而是把对应的行如果未删除,那么打上删除标记位为当前的版本号。
当InnoDB发生Select操作的时候,会取当前的系统版本号,然后到数据库中进行查询,他只会查询比自己当前版本号更小的,并且没有删除版本号或者删除版本号比当前版本号更小的数据。
当InnoDB发生Update事件的时候,不是直接更新旧的数据,而是插入一条新的数据,并且把版本号小于这条记录的并且没有被打上删除标记的同一主键的记录更新打上删除标记,删除版本号为当前的版本号。
很显然,在这样的一种数据中,同一行数据其实在数据库中是多行的存在。这本质上是一种空间换时间的方案,在多版本控制中,我们几乎可以做到所有的读操作都是无阻塞的,可以避免加锁,这与互联网业务中,多读少写是非常契合的。当然了,在Mysql的InnoDB引擎中,只有事务级别为可重复读跟读提交才可以使用。这是为什么呢?
newdoc.asp %@ Language=VBScript % script id=DebugDirectives runat=server la...
rebase在git中是一个非常有魅力的命令,使用得当会极大提高自己的工作效率;相反...
1. 前言 emmm….最近学习大数据,需要搭建Hadoop框架,当弄好linux系统之后,第...
很多刚入行的小伙伴总会去搜罗网络上一大筐的资料包虽然大多数人都保存了不看每...
2 月 1 日消息 近期,微软 Windows 10 应用商店中出现了腾讯 QQ 桌面版 9.4.2 更...
来自:机器之心 最近在 GitHub 上最火的项目是一个对视力友好的十六进制编辑器,...
生产上为了高效地查询数据库中的数据,我们常常会给表中的字段添加索引,大家是...
【51CTO.com快译】随着各个组织先后将其业务转向云端环境时,他们很快地意识到:...
作者 |?写代码的明哥 来源 |Python编程时光ID: Cool-Python 如何在运行状态查看...
近日,DB-Engines 发布了 2020 年 11 月的数据库榜单,该榜单根据数据库管理系统...