当前位置: 首页 > 科技观察

程序员经典面试题,MySQL并发读写时,需要加锁吗?

时间:2023-03-22 17:34:44 科技观察

这是一道经典的程序员面试题。在Mysql中,如果有多个事务同时访问同一行数据,是否需要加锁?我们都知道Mysql中有行锁。如果有多个事务同时修改同一行数据,就需要加锁来防止并发问题。那么,如果一个事务修改了数据,另一个事务读取了这个数据,我们需要加锁吗?答案不一定。其实Mysql的很多数据库引擎为了提高并发性能,都实现了多版本并发控制,也就是我们常说的MVCC。事实上,除了Mysql,其他知名的关系型数据库,如Oracle、PostgreSql等也实现了多版本并发控制。虽然实现方式不同,但它们的本质都是实现非阻塞读取,即即使是对这一行数据进行更改时,也可以读取到。那么,Mysql是如何实现MVCC的呢?在Mysql的每一行数据中,除了我们定义的数据列外,还有两个隐藏的列,一个是数据变化时间,一个是这行数据的删除时间,当然这个时间不是一个简单的时间戳,但严格增加系统版本号。当InnoDB发生Insert事件时,将插入当前行,并将获取的系统版本号作为数据版本号。当InnoDB中出现Delete时间时,当前行不会被删除,但是如果对应的行还没有被删除,那么删除标志会被标记为当前版本号。当InnoDB发生Select操作时,会取当前系统版本号,然后到数据库中查询。只会查询比自己当前版本号小的版本号,不会删除版本号,也不会删除比当前版本号高的版本号。小数据。当InnoDB发生Update事件时,不是直接更新旧数据,而是插入一条新数据,版本号小于这条记录且未打删除标记的同一主键的记录更新带有删除标记,版本被删除。number是当前版本号。显然,在这样一种数据中,同一行数据实际上存在于数据库中的多行中。这本质上是一种以空间换时间的解决方案。在多版本控制中,我们可以让几乎所有的读操作都变成非阻塞的,避免加锁。这与互联网业务的读多写少有很大区别。合身。当然,在Mysql的InnoDB引擎中,只有在事务级别是repeatableread和readcommit的情况下才能使用。为什么是这样?