数据库乐观锁与悲观锁

前面说到了数据库的隔离级别,隔离性是数据库中数据有意义的条件之一,而不同的隔离级别,归根到底其实是在读和写的操作中对表、事务后者是表进行对应的锁定操作,所以下面简单总结下数据库的两种类型锁:乐观和悲观锁,很多是概念性的东西和个人理解,不足之处也请指正。

一、锁的概念

  简单说说数据库锁的概念,和多线程中的锁类似,数据库中对数据的锁定其实也是保证数据同步的主要手段,它表现出来的是:并发下,线程之间对数据库数据的操作是单方的。而在数据库里面主要有两种锁手段保证这种并发下的线程单方面操作:悲观锁和乐观锁,两者对数据同步采取的机制不同,下面逐一进行简单总结。

二、悲观锁

  1、概念。悲观锁是这样一种概念:当线程访问数据库的某些数据时,我先给数据上锁,然后进行事务处理,当事务提交(or失败回滚)成功的时候,我才释放这些数据的锁,其他线程才能访问这些数据。悲观锁其实和多线程中的锁同步概念是很类似的。总的来说,悲观锁对高并发持一种悲观的态度:它总是认为系统数据的访问时高并发的,所以需要在操作数据(包括读和写)的第一时间就获取锁,这和下面的乐观锁形成鲜明的对比。

  2、实现原理。悲观锁的实现原理和编程中的多线程差不多,数据库中的数据都会有本身对应的锁(有数据库自己提供),当该数据的锁被对应线程获得时,其他访问该数据的线程处于阻塞状态,只有该线程释放该锁时,该数据才可再次被访问。总的来说,悲观锁原理和线程中的lock概念差不多。

  3、具体用法。乐观锁只是一种概念而已,在mysql中,一般的用法表现是利用sql语句的for update指令对数据进行锁定。例如,select * from user where user_id=1 for update这条语句,它是这样一种意思:我要拿user表中user_id为1的数据出来并且后面我会对该行数据进行更新操作,所以请数据库帮我锁定该条数据不 让其他线程访问(读写都不行),这时就会导致其他访问该数据的线程处于阻塞状态。

三、乐观锁

  1、概念。相比于上面的悲观锁,乐观锁的概念和其不同,它不会在业务持续开始对数据库进行事务操作时就开始给数据库上锁,而是将数据的同步时间后移到数据提交的时候再进行检查,检查完数据是否有冲突再进行提交。乐观锁对并发问题持有一种乐观的态度:它总是假设系统的数据在一段时间内不会有太多改变(即写跟新数据的并发线程远远小于读的线程)。

  2、实现原理。乐观锁其实并没有在数据库中对数据进行加锁的操作,它不会直接锁定数据,而是采用一种手段来标记数据的版本,在事务开始的时候先获取版本,然后事务结束的时候对比版本是否有改变,如果没改变,直接将事务提交成功,更新数据;否则告诉用户版本冲突,不可执行事务。

  而具体来说,实现乐观锁的原理大概有两种:一个是版本号的记录,另外一个就是时间节点的记录。前者数据库会记录每次数据修改的版本号,用于标记;后者则根据数据修改时间进行标记操作。具体的实现原理就不展开说,有兴趣的可以百度谷歌MVCC和CAS进行了解。

四、悲观锁VS乐观锁。

   所以,我们应该在悲观和乐观锁的两者之间如何抉择呢?个人理解有一下总结,具体用法还是看业务需要:

  1、数据更新(写操作)并发严重,采用悲观锁可以保证程序执行更新操作成功的次数,而采用乐观锁可以提高响应的速度但是执行更新操作成功次数会降低;

  2、复杂业务采用悲观锁会容易死锁,乐观锁不存在这方面的问题;

  3、业务回滚的代价:若回滚代价过大则采用悲观锁,否则再考虑是否采用乐观锁;

  4、对于写读读少的,采用悲观锁更好;读多与写的话考虑乐观锁。

  

时间: 2024-12-19 08:00:03

数据库乐观锁与悲观锁的相关文章

[数据库事务与锁]详解七: 深入理解乐观锁与悲观锁

注明: 本文转载自http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.

web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)

这篇文章讲了 1.同步异步概念(消去很多疑惑),同步就是一件事一件事的做:sychronized就是保证线程一个一个的执行. 2.我们需要明白,锁机制有两个层面,一种是代码层次上的,如Java中的同步锁,典型的就是同步关键字synchronized ( 线    程级别的).另一个就是数据库层次上的,比较典型的就是悲观锁和乐观锁. 3.常见并发同步案例分析   附原文链接 http://www.cnblogs.com/xiohao/p/4385508.html 对于我们开发的网站,如果网站的访问

php使用数据库的并发问题(乐观锁与悲观锁)

在php与数据库的交互中,如果并发量大,并且都去进行数据库的修改的话,就有一个问题需要注意.数据的锁问题.就会牵扯数据库的事务跟隔离机制 数据库事务依照不同的事务隔离级别来保证事务的ACID特性,也就是说事务不是一开启就能解决所有并发问题.通常情况下,这里的并发操作可能带来四种问题: 更新丢失:一个事务的更新覆盖了另一个事务的更新,这里出现的就是丢失更新的问题. 脏读:一个事务读取了另一个事务未提交的数据. 不可重复读:一个事务两次读取同一个数据,两次读取的数据不一致. 幻象读:一个事务两次读取

聊聊数据库乐观锁和悲观锁,乐观锁失败后重试

在写入数据库的时候需要有锁,比如同时写入数据库的时候会出现丢数据,那么就需要锁机制. 数据锁分为乐观锁和悲观锁,那么它们使用的场景如下: 1. 乐观锁适用于写少读多的情景,因为这种乐观锁相当于JAVA的CAS,所以多条数据同时过来的时候,不用等待,可以立即进行返回. 2. 悲观锁适用于写多读少的情景,这种情况也相当于JAVA的synchronized,reentrantLock等,大量数据过来的时候,只有一条数据可以被写入,其他的数据需要等待.执行完成后下一条数据可以继续. 他们实现的方式上有所

数据库-乐观锁和悲观锁

写在前面: 锁根据其使用的方式可以划分为:乐观锁和悲观锁.乐观锁即乐观并发控制,悲观锁即悲观并发控制,他们是处理并发控制时主要采用的技术手段.其中,悲观锁正是数据库本身提供的锁机制实现的. 悲观锁: 悲观锁(Pessimistic Concurrency Control)缩写为PCC.从字面意义上理解,就是每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会进入阻塞状态,直到它拿到锁.在传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,

数据库的锁:行级锁、表锁、乐观锁、悲观锁的实现原理

一.相关名词 表级锁(锁定整个表) 页级锁(锁定一页) 行级锁(锁定一行) 共享锁(S锁,MyISAM 叫做读锁) 排他锁(X锁,MyISAM 叫做写锁) 悲观锁(抽象性,不真实存在这个锁) 乐观锁(抽象性,不真实存在这个锁) 二.InnoDB与MyISAM Mysql 在5.5之前默认使用 MyISAM 存储引擎,之后使用 InnoDB .查看当前存储引擎: show variables like '%storage_engine%'; MyISAM 操作数据都是使用的表锁,你更新一条记录就要

数据库的乐观锁与悲观锁

概述 无论是悲观锁还是乐观锁,都是人们定义出来的概念,是一种读取和修改数据的并发访问策略,由应用和业务需求来确定的.其实不仅仅是数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.tair等都有类似的概念.所以,不要把乐观锁和悲观锁狭义的理解为DBMS中的概念,更不要把他们和数据中提供的锁机制(行锁.表锁.排他锁.共享锁)混为一谈.在DBMS中,只是利用数据库本身提供的锁机制和数据的版本(version)来实现的这两种不同的并发访问策略. 悲观锁 正如其名,它指的是对数据

数据库乐观锁和悲观锁的理解和实现

数据的锁定分为两种,第一种叫作悲观锁,第二种叫作乐观锁. 1.悲观锁,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.[数据锁定:数据将暂时不会得到修改] 2.乐观锁,认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息.让用户决定如何去做. 理解: 1. 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段.处理完业务逻辑开始更新

乐观锁和悲观锁的区别

一分钟教你知道乐观锁和悲观锁的区别 分类: 数据库(Database)2014-07-08 14:06 17588人阅读 评论(2) 收藏 举报 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁. 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,

乐观锁,悲观锁

转:一分钟教你知道乐观锁和悲观锁的区别 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁. 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个