书说 MySQL 的悲观锁和乐观锁
什么是乐观锁?什么是悲观锁?
悲观锁:
悲观锁是一种基于悲观态度的控制机制(最坏的程度想,每次并发一定会造成阻塞),用于防止数据冲突。它采取预防性措施,在修改数据之前将其锁定,并在操作完成后释放锁,以此来确保数据的一致性和完整性。悲观锁通常用于并发环境下的数据库操作,是数据库本身实现锁的一种方式。
在悲观锁机制下,当一个使用者要访问并修改数据时,首先会获取该数据的锁,如果锁已经被其他使用者所拥有,那么就会阻塞当前使用者,知道对应的锁被释放,这种悲观的态度认为数据冲突是不可避免的,因此在修改数据之前先锁定数据,以防止冲突的发生。
适用场景:
- 高并发且数据竞争比较激烈的情况:当多个事务需要访问并修改同一份数据的时候,使用悲观锁可以保证数据在任一时刻只被一个事务访问,和修改,从而避免数据的不一致和脏读现象。
- 数据一致性较高的场景。比如在金融或医疗场景中,不允许任何时候出现数据不一致或者脏读
- 写操作频繁的场景:如果系统中写操作(更新、删除等)远多于读操作(查询),那么使用悲观锁可以有效的保证数据的一致性。
- 事务执行时间较长:在一个业务流程时间较长的情况下,使用悲观锁可以保证这个事务执行期间数据不会被其他线程修改
乐观锁:
乐观锁是一种基于版本控制的并发控制机制。在乐观锁的思想中,认为数据的访问造成冲突的概率是很低的,因此不进行直接加锁的操作,但在数据更新时会进行版本比对,以此来确保数据的一致性。
乐观锁主要是依据时间戳和版本号来实现。在每次数据更新时,先获取当前版本或时间戳,然后在更新时对比版本号或时间戳是否一致,若一致则成功,否则表示数据已经被其他线程修改,更新失败。
适用场景:
- 写操作较少
- 数据冲突较少
- 重试成本低:重试不会导致大量的计算或者I/O
- 系统能够容忍一定的失败
实验大家可以跟着腾讯云做一下
插播一条:
为什么布隆过滤器就比分布式锁性高?
首先我们要明白布隆过滤器是什么?
百度百科这样定义它:布隆过滤器(Bloom Filter)它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。换句话来说,布隆过滤器就是有一个初值都为零的 bit 数组和一组哈希函数构成的,用来快速判断集合中是否存在某个元素的数据结构。
基于哈希函数这种特性,布隆过滤器中的元素只能添加不能删除,由于涉及 hashcode 的判断依据,删除会导致误判率增加。
同时在数据量较大的情况下,不用数据经过同样的一组规则定义的哈希函数有可能值相同,那么也就是说可能会发生误判的情况。
总结来说:一个元素如果判断结果存在,则这个元素可能存在,但是判断结果不存在,这个元素一定不存在
那分布式锁是什么东西呢?
分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。
那么为什么布隆过滤器性能就比分布式锁性能高呢?
首先请求的数据经过布隆过滤器过滤后很大概率就可以直接判断是否存储在于系统中,不存在则直接返回了,减少了很多查询的过程,直接在内存层面做了判断。
而只要涉及到锁就需要先获取锁,再释放锁,而依据红锁算法,分布式锁的获取又涉及到集群中大部分机器都加锁成功,而后进行数据操作。这个过程中集群的通信、网络的波动、请求进入的判断都会增加系统性能的消耗,因此布隆过滤器的性能可以说强出分布式锁一大截。(分布式锁主要适用于需要数据严格同步和一致性的场景)