返回顶部
首页 > 资讯 > 数据库 >什么是乐观锁、悲观锁和MVCC
  • 933
分享到

什么是乐观锁、悲观锁和MVCC

2024-04-02 19:04:59 933人浏览 八月长安
摘要

本篇内容主要讲解“什么是乐观锁、悲观锁和mvcC”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是乐观锁、悲观锁和MVCC”吧!在数据库的实际使用过程中,我们

本篇内容主要讲解“什么是乐观、悲观锁和mvcC”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是乐观锁、悲观锁和MVCC”吧!

数据库的实际使用过程中,我们常常会遇到不希望数据被同时写或者读的情景,例如秒杀场景下,两个请求同时读到系统还有库存1个,然后又先后把库存更新为0,这时候就会出现超卖的情况,这时候货物的实际库存和我们的记录就会对应不上了。

为了解决这种资源竞争导致的数据不一致等问题,我们需要有一种机制来进行保证数据的正确访问和修改,而在数据库中,这种机制就是数据库的并发控制。其中乐观并发控制,悲观并发控制和多版本并发控制是数据库并发控制主要采用的技术手段。

悲观并发控制
一、本质

维基百科:在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,PessimisticConcurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

事实上我们常说的悲观锁并不是一种实际的锁,而是一种并发控制的思想,悲观并发控制对于数据被修改持悲观的态度,认为数据被外界访问时,必然会产生冲突,所以在数据处理的过程中都采用加锁的方式来保证对资源的独占。

数据库的锁机制其实都是基于悲观并发控制的观点进行实现的,而且按照实际使用情况,数据库的锁又可以分为许多种类,具体可以见我后面的文章。

二、实现方式

数据库悲观锁的加锁流程大致如下:

  1. 开始事务后,按照操作类型给需要加锁的数据申请加某一类锁:例如共享行锁等

  2. 加锁成功则继续后面的操作,如果数据已经被加了其他的锁,而且和现在要加的锁冲突,则会加锁失败(例如已经加了排他锁),此时需等待其他的锁释放(可能出现死锁)

  3. 完成事务后释放所加的锁

三、优缺点

优点:

悲观并发控制采取的是保守策略:“先取锁,成功了才访问数据”,这保证了数据获取和修改都是有序进行的,因此适合在写多读少的环境中使用。当然使用悲观锁无法维持非常高的性能,但是在乐观锁也无法提供更好的性能前提下,悲观锁却可以做到保证数据的安全性。

缺点:

由于需要加锁,而且可能面临锁冲突甚至死锁的问题,悲观并发控制增加了系统的额外开销,降低了系统的效率,同时也会降低了系统的并行性。

乐观并发控制
一、本质

维基百科:在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,OptimisticConcurrency Control,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。

乐观并发控制对数据修改持乐观态度,认为即使在并发环境中,外界对数据的操作一般是不会造成冲突,所以并不会去加锁,而是在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,则让返回冲突信息,让用户决定如何去做下一步,比如说重试或者回滚。

可以看出,乐观锁其实也不是实际的锁,甚至没有用到锁来实现并发控制,而是采取其他方式来判断能否修改数据。乐观锁一般是用户自己实现的一种锁机制,虽然没有用到实际的锁,但是能产生加锁的效果。

二、实现方式

CAS(比较与交换,Compare and swap) 是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。实现非阻塞同步的方案称为“无锁编程算法”( Non-blocking alGorithm)。

乐观锁基本都是基于 CAS(Compare and swap)算法来实现的。我们先来看下CAS过程,一个CAS操作的过程可以用以下c代码表示:

intcas(long*addr,longold,longnew) {          if(*addr!= old)         return0;     *addr= new;     return1; } 复制代码

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。整个CAS操作是一个原子操作,是不可分割的。

乐观锁的实现就类似于上面的过程,主要有以下几种方式:

  1. 版本号标记:在表中新增一个字段:version,用于保存版本号。获取数据的时候同时获取版本号,然后更新数据的时候用以下命令:updatexxx set version=version+1,… where … version="old version" and ....。这时候通过判断返回结果的影响行数是否为0来判断是否更新成功,更新失败则说明有其他请求已经更新了数据了。

  2. 时间戳标记:和版本号一样,只是通过时间戳来判断。一般来说很多数据表都会有更新时间这一个字段,通过这个字段来判断就不用再新增一个字段了。

  3. 待更新字段:如果没有时间戳字段,而且不想新增字段,那可以考虑用待更新字段来判断,因为更新数据一般都会发生变化,那更新前可以拿要更新的字段的旧值和数据库的现值进行比对,没有变化则更新。

  4. 所有字段标记:数据表所有字段都用来判断。这种相当于就、不仅仅对某几个字段做加锁了,而是对整个数据行加锁,只要本行数据发生变化,就不进行更新。

三、优缺点

优点:

乐观并发控制没有实际加锁,所以没有额外开销,也不错出现死锁问题,适用于读多写少的并发场景,因为没有额外开销,所以能极大提高数据库的性能。

缺点:

乐观并发控制不适合于写多读少的并发场景下,因为会出现很多的写冲突,导致数据写入要多次等待重试,在这种情况下,其开销实际上是比悲观锁更高的。而且乐观锁的业务逻辑比悲观锁要更为复杂,业务逻辑上要考虑到失败,等待重试的情况,而且也无法避免其他第三方系统对数据库的直接修改的情况。

多版本并发控制
一、本质

维基百科: 多版本并发控制(Multiversion concurrency control, MCC 或 MVCC),是数据库管理系统常用的一种并发控制,也用于程序设计语言实现事务内存。

乐观并发控制和悲观并发控制都是通过延迟或者终止相应的事务来解决事务之间的竞争条件来保证事务的可串行化;虽然前面的两种并发控制机制确实能够从根本上解决并发事务的可串行化的问题,但是其实都是在解决写冲突的问题,两者区别在于对写冲突的乐观程度不同(悲观锁也能解决读写冲突问题,但是性能就一般了)。而在实际使用过程中,数据库读请求是写请求的很多倍,我们如果能解决读写并发的问题的话,就能更大地提高数据库的读性能,而这就是多版本并发控制所能做到的事情。

与悲观并发控制和乐观并发控制不同的是,MVCC是为了解决读写锁造成的多个、长时间的读操作饿死写操作问题,也就是解决读写冲突的问题。MVCC 可以与前两者中的任意一种机制结合使用,以提高数据库的读性能。

数据库的悲观锁基于提升并发性能的考虑,一般都同时实现了多版本并发控制。不仅是Mysql,包括oraclepostgresql等其他数据库系统也都实现了MVCC,但各自的实现机制不尽相同,因为MVCC没有一个统一的实现标准。

总的来说,MVCC的出现就是数据库不满用悲观锁去解决读-写冲突问题,因性能不高而提出的解决方案。

二、实现方式

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。每个事务读到的数据项都是一个历史快照,被称为快照读,不同于当前读的是快照读读到的数据可能不是最新的,但是快照隔离能使得在整个事务看到的数据都是它启动时的数据状态。而写操作不覆盖已有数据项,而是创建一个新的版本,直至所在事务提交时才变为可见。

当前读和快照读

什么是mysql InnoDB下的当前读和快照读?

当前读

像select lock in share mode(共享锁),select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

快照读

像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是未提交读和串行化级别,因为未提交读总是读取最新的数据行,而不是符合当前事务版本的数据行。而串行化则会对所有读取的行都加锁

三、优缺点

MVCC 使大多数读操作都可以不用加锁,这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

适用场景
一、悲观锁

  1. 用来解决读-写冲突和写-写冲突的的加锁并发控制

  2. 适用于写多读少,写冲突严重的情况,因为悲观锁是在读取数据的时候就加锁的,读多的场景会需要频繁的加锁和很多的的等待时间,而在写冲突严重的情况下使用悲观锁可以保证数据的一致性

  3. 数据一致性要求高

  4. 可以解决脏读,幻读,不可重复读,第一类更新丢失,第二类更新丢失的问题

二、乐观锁

  1. 解决写-写冲突的无锁并发控制

  2. 适用于读多写少,因为如果出现大量的写操作,写冲突的可能性就会增大,业务层需要不断重试,这会大大降低系统性能

  3. 数据一致性要求不高,但要求非常高的响应速度

  4. 无法解决脏读,幻读,不可重复读,但是可以解决更新丢失问题

三、MVCC

  1. 解决读-写冲突的无锁并发控制

  2. 与上面两者结合,提升它们的读性能

  3. 可以解决脏读,幻读,不可重复读等事务问题,更新丢失问题除外

到此,相信大家对“什么是乐观锁、悲观锁和MVCC”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

您可能感兴趣的文档:

--结束END--

本文标题: 什么是乐观锁、悲观锁和MVCC

本文链接: https://lsjlt.com/news/61989.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 什么是乐观锁、悲观锁和MVCC
    本篇内容主要讲解“什么是乐观锁、悲观锁和MVCC”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是乐观锁、悲观锁和MVCC”吧!在数据库的实际使用过程中,我们...
    99+
    2024-04-02
  • 悲观锁和乐观锁是什么
    悲观锁和乐观锁是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。乐观锁( Optimistic Locking )乐观锁( ...
    99+
    2024-04-02
  • 什么是悲观锁和乐观锁
    什么是悲观锁和乐观锁?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 悲观锁(Pessimistic Lock), 顾...
    99+
    2024-04-02
  • MySQL中乐观锁和悲观锁是什么
    这篇文章给大家分享的是有关MySQL中乐观锁和悲观锁是什么的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。数据库管理系统中并发控制的任务是确保在多个事务同时存取数据库中同一数据不破...
    99+
    2024-04-02
  • mysql 乐观锁和悲观锁
    悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层...
    99+
    2023-09-02
    mysql 数据库 java
  • Java悲观锁和乐观锁机制是什么
    本篇内容主要讲解“Java悲观锁和乐观锁机制是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java悲观锁和乐观锁机制是什么”吧!1、锁机制简介并发编程中一个最关键的问题,多线程并发处理同一...
    99+
    2023-06-02
  • MySQL中的乐观锁,悲观锁和MVCC全面解析
    前言 在数据库的实际使用过程中,我们常常会遇到不希望数据被同时写或者读的情景,例如秒杀场景下,两个请求同时读到系统还有库存1个,然后又先后把库存更新为0,这时候就会出现超卖的情况,这时候货物的实际库存和我们的记录就...
    99+
    2022-05-19
    MySQL 乐观锁 MySQL 悲观锁 MySQL mvcc
  • MySQL乐观锁和悲观锁介绍
    乐观锁 乐观锁不是数据库自带的,需要我们自己去实现。乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去...
    99+
    2024-04-02
  • mybatis使用乐观锁和悲观锁
    悲观锁和乐观锁的概念: 悲观锁:就是独占锁,不管读写都上锁了。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲...
    99+
    2023-08-30
    mysql
  • mysql乐观锁和悲观锁有什么区别
    本篇内容主要讲解“mysql乐观锁和悲观锁有什么区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql乐观锁和悲观锁有什么区别”吧! ...
    99+
    2024-04-02
  • MYSQL中悲观锁和乐观锁的作用是什么
    这篇文章给大家介绍MYSQL中悲观锁和乐观锁的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。  悲观锁(Pessimistic Lock)  悲观锁(Pessimistic ...
    99+
    2024-04-02
  • 悲观锁,乐观锁的概念
    悲观锁:顾名思义,就是很悲观,它指的是对数据被外界(包括本系统当前的其他事务,以及来自其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁实现,往往依...
    99+
    2024-04-02
  • MySQL怎么处理乐观锁和悲观锁
    MySQL中可以通过以下两种方式来处理乐观锁和悲观锁: 乐观锁:在MySQL中,可以通过使用版本号或时间戳来实现乐观锁。在数据库...
    99+
    2024-04-09
    MySQL
  • mysql中乐观锁和悲观锁有什么区别
    mysql中乐观锁和悲观锁的区别有:1.概念不同;2.使用场景不同;3.实现方式不同;4.特点不同;mysql中乐观锁和悲观锁的区别有以下几点概念不同mysql中乐观锁是对加锁持有一种乐观的态度,可以先进行业务操作,不到最后一步不进行加锁,...
    99+
    2024-04-02
  • java中悲观锁和乐观锁有什么区别
    本篇文章给大家分享的是有关java中悲观锁和乐观锁有什么区别,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java可以用来干什么Java主要应用于:1. web开发;2. An...
    99+
    2023-06-14
  • MySQL中的悲观锁与乐观锁
    在关系型数据库中,悲观锁与乐观锁是解决资源并发场景的解决方案,接下来将详细讲解🔎一下这两个并发解决方案的实际使用及优缺点。 首先定义一下数据库,做一个最简单的库存表,如下设计: CREATE TA...
    99+
    2022-05-15
    MySQL 悲观锁 MySQL 乐观锁
  • MySQL乐观锁和悲观锁具体实现
    目录前言锁分类表结构悲观锁乐观锁适用场景总结前言 对于mysql中的乐观锁和悲观锁,可能很多的开发者还不是很熟悉,并不知道其中具体是如何实现的。本文就针对这个问题做一个实际案例演示,让你彻底明白这两种锁的区别。 锁分类 ...
    99+
    2024-04-02
  • MySQL中乐观锁和悲观锁的区别
    这篇文章将为大家详细讲解有关MySQL中乐观锁和悲观锁的区别,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。悲观锁在关系数据库管理系统中,悲观并发控制(悲观锁...
    99+
    2024-04-02
  • MySQL乐观锁和悲观锁如何实现
    这篇文章主要介绍了MySQL乐观锁和悲观锁如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MySQL乐观锁和悲观锁如何实现文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2024-04-02
  • mysql悲观锁和乐观锁如何实现
    悲观锁是在对数据进行操作之前就先加锁,防止其他事务对数据进行修改,从而确保数据的一致性。在MySQL中,可以通过使用SELEC...
    99+
    2024-05-08
    mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作