并发控制:(二)乐观锁 悲观锁

  

悲观锁:(pessimistic locking)
假定:发生冲突的概率比较高,
实现:在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。这样其他事务如果想操作该记录,需要等待锁的释放
特点: 当并发量较大,频繁访问时,等待时间较长,并发访问性不好
例如: java的synchronized,SqlServer页级锁,Oracle行级锁

乐观锁:(optimistic locking)
假设:发生冲突的概率比较低
实现:在提交对记录的更改时才将对象锁住,提交前需要检查数据的完整性

比如,现有两个事务A和B,并且认为A和B是两个原子操作。
A:Cat c = findById(catId);
c.setName("NewCat");
B: update(c)
那么,在B提交前,会锁住c对象(这里代码中并没有锁操作,因为锁操作是B提交前由数据库完成的)。
同时,为了避免A执行后与B执行前之间的这段时间,c对象被其他线程改变了,所以提交前要检查数据的一致性。
检查数据的一致性的方式可以是通过时间戳,或者用自增长的整数表示数据版本号(例如Hibernate、Morphia中的@Version)
如果检查数据已经被改变了,需要回到步骤A重新运行程序,直到提交成功。或者是直接抛出异常,这要看锁的策略了。
由于假定发生冲突的概率比较低的,所以这种重试是可以容忍的,但如果是高并发,就会影响性能了。
这种控制方式也叫乐观并发控制(Optimistic concurrency control)

特点:
读取和改变该对象时不加锁,提交变更前加锁
乐观锁加锁时间要比悲观锁短
可以用较大的锁粒度获得较好的并发访问性能
会增加并发用户读取对象的次数(检查数据一致性时会多一步查询)

时间: 2024-10-09 03:58:45

并发控制:(二)乐观锁 悲观锁的相关文章

[转]数据库并发控制 乐观锁,悲观锁

在数据库中,并发控制有乐观锁和悲观锁之间,什么时候用乐观锁比较好什么时候用悲观锁比较好? 实际生产环境里边,如果并发量不大,完全可以使用悲观锁定的方法,这种方法使用起来非常方便和简单.但是如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以就要选择乐观锁定的方法. 悲观锁假定其他用户企图访问或者改变你正在访问.更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁.悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长

最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制. 乐观锁适用于多

【多线程】公平锁/非公平锁、乐观锁/悲观锁

公平锁/非公平锁(多线程执行顺序的维度) 概念理解 公平锁:加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,先来先得. 非公平所:线程加锁时直接尝试获取锁,获取不到就自动到队尾等待. 例子 ReentrantLock 同时支持两种锁 //创建一个非公平锁,默认是非公平锁 Lock nonFairLock= new ReentrantLock(); Lock nonFairLock= new ReentrantLock(false); //创建一个公平锁,构造传参true Lock

AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念

众所周知,JDK提供了AtomicInteger保证对数字的操作是线程安全的,线程安全我首先想到了synchronized和Lock,但是这种方式又有一个名字,叫做互斥锁,一次只能有一个持有锁的线程进入,再加上还有不同线程争夺锁这个机制,效率比较低,所以又称“悲观锁”. 但是相应的有了乐观锁的概念,他的思路就是,它不加锁去完成某项操作,如果因为冲突失败就重试,直到成功为止.这种说的比较抽象,我们直接拿AtomicInteger源码举例,因为AtomicInteger保证线程安全就是因为使用了乐观

Mysql锁机制--乐观锁 & 悲观锁

前言 mysql的并发操作时而引起的数据的不一致性(数据冲突): 丢失更新:两个用户(或以上)对同一个数据对象操作引起的数据丢失. 解决方案:1.悲观锁,假设丢失更新一定存在:sql后面加上for update:这是数据库的一种机制. 2.乐观锁,假设丢失更新不一定发生.update时候存在版本,更新时候按版本号进行更新. 第一部分 悲观锁 1 概念 悲观锁,正如其名,它指的是对数据被外界(包括当前系统的其它事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于

解决并发问题,数据库常用的两把锁——悲观锁,乐观锁

一.概念: 乐观锁:适用于写少读多的情景,因为这种乐观锁相当于java的cas(比较并替换),所以多条数据同事过来的时候不用等待,可以立即进行返回 悲观锁:适用于写多读少的情景,这种情况也相当于java的synchronized,reentrantLock等,大量数据过来的时候,只有一条被写入,其他数据需要等待,智行完成后下一条数据继续. 二:实现方式: 乐观锁:采用版本号的方式.即当前版本号如果对应上了就可以写入数据,如果判断当前版本号不一致,那么就不会更新成功. 比如 update tabl

Django - ORM - 事务, 乐观锁, 悲观锁

事务 概念 Transaction 事务:一个最小的不可再分的工作单元:通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元) 一个完整的业务需要批量的DML(insert.update.delete)语句共同联合完成 事务只和DML语句 ( 数据库操作语句 ) 有关,或者说DML语句才有事务.这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同 特性 ? 原子性(A) 事务是最小单位,不可再分 ? 一致性(C) 事务要求所有的DML语句操作的时候,必须保证同时成

Mysql:行锁 表锁 乐观锁 悲观锁 读锁 写锁

锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足.在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 行锁 锁定整个行数据,开销大,加锁慢,会出现死锁.锁定粒度小,发生锁冲突的概率低,并发度高. 表锁 锁定整个表数据,开销小,加锁快,不会出现死锁.锁定粒度大,发生锁冲突概率高,并发度低. 悲观锁 每次取数据时都认为别人会修改,所以每次取数据的时候都会上锁,这样别人想拿这个数据就会被阻

乐观锁悲观锁

老生常谈,这个写的挺好. http://blog.csdn.net/hongchangfirst/article/details/26004335 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁. 乐观锁(Optimistic Lock), 顾名思义,就是很乐观