For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
java编程开发随着互联网的不断发展而被越来越多的程序员掌握,今天我们就通过案例分析来简单了解一下,java编程程序员需要掌握哪些数据库锁类型。
自增锁
我们在创建表时,ID这一列通常会声明AUTO_INCREMENT属性,表示该列是自动递增的。之后我们在进行插入时,可以不用指定ID列的值,MySQL会自动且递增的给该列赋值。
对于MySQL提供的这一功能,我们应该会有如下一些疑问:
自增的值保存在什么地方?
一定能保证连续递增吗,会不会出现不连续情况?
自增是如何实现的,如何保证值不会重复?
自增的值保存在什么地方?我们应该能想到的是,在每次插入数据时,MySQL能够自动进行赋值和自增,缓存在内存中的概率性大。
的确如此,在MySQL7及之前,自增值保存内存里面,并且没有进行持久化。这也就产生一个问题,当数据库重启后,一次打开表时,MySQL会找到这个表中自增列的当前大值maxId,然后将maxId+1作为这个表的自增值。但是这个自增值不一定和重启之前值一样。
举例来说,假设在重启之前,将这个表中自增列为25的大一条记录删除了,当我们进行插入时,自增的值并不会回退到25,而是使用26。但是在重启之后,因为查询到自增列的当前大值maxId=24,自增值回退到了25。
在MySQL8版本后,自增值增加了持久化能力,记录在undo_log里面,重启后,靠undo_log进行恢复,也就不会出现之前的问题了。
自增的值会不会出现不连续的现象?要回答这个问题,先要知道MySQL是如何给一条未指定自增列的插入SQL自动赋值和递增自增值的。具体来说分为下面几步:
当MySQL发现插入SQL未指定自增列的值时,先从内存获取当前的自增值inc
修改插入SQL,指定自增列的值为inc
将内存中当前的自增值进行+1操作
继续执行SQL,进行插入
假设在后一步执行SQL,进行插入时出现了Duplicatekeyerror。那么事务就会进行回滚。该行插入失败。但是我们发现自增列的值inc却已经进行了+1操作。下一次再进行插入时,获取到的自增列的值和数据库中已经存在的自增列的值就会不连续。因为上一次的事务插入的行因为失败回滚了。
为什么在事务回滚时,不一起把自增列的值一起回退了。回退之后不就能保证自增值递增且连续了。我们可以想一下,如果回退了,是不是就会更有可能出现Duplicatekeyerror问题,因为你不能保证自增之后,其他事务是否已经使用了自增之后的值。而且解决这个问题的成本也比较高,所以MySQL中的自增值,只保证了自增,没有保证连续。
行级锁
MyISAM存储引擎只有表锁,是不支持行级锁的,而InnoDB存储引擎不仅支持事务,还支持更高效和细粒度的行级锁。总的来说,共有三种重要的行级锁机制。
行锁(RecordLock)
我们知道,MySQL使用多版本并发控制(MVCC)解决了不可重复读问题。并且保证了读-写不会产生冲突,也没有使用锁。对于普通的select...操作,使用的就是MVCC,这种读取也叫做“快照读”或者“一致性读”;也就是说,读取的数据来自于一致性视图,也就是历史数据。
如果查询都是这样,不就不需要行级锁了吗?其实,在很多业务场景下,“快照读”并不能满足需求,并且也不能解决丢失更新、幻读等事务类问题。此时就需要读取新的数据并进行加锁后再处理。这种读取也被称为“锁定读”。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加抖音太原达内IT培训学习了解。