详解什么是悲观锁和乐观锁?

悲观锁和乐观锁是面试时必问的,也是开发过程中重要的知识点,是作为一个程序员必须要掌握的,那么你知道什么是悲观锁和乐观锁吗?

1. 悲观与乐观:

悲观认为世界变幻无常,人注定要遭受苦难,因而陷入悲观绝望,甚至认为生不如死,什么事情都往不好的方面想.,很消极.
乐观泛指对宇宙、社会、人生充满信心和希望的态度、观点和理论。在伦理学说史上,对什么事情都保存乐观、积极向上的态度
2. 那么悲观锁和乐观锁呢?
悲观锁和乐观锁和悲观与乐观的意思差不多

悲观锁: 就像是有悲观消极的态度,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁
悲观锁假定会发生并发冲突的可能,于是屏蔽一切可能违反数据完整性的操作

Java synchronized就是悲观锁的其中一种,每次线程要修改数据的时候都先获得锁,保证同一时刻只有一个线程能操作数据,其他线程则会被block.

乐观锁: 就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用加字段比较的方法,如版本号等机制。乐观锁适用于读多写少的应用类型,这样可以提高吞吐量.
3. 详解什么是版本号机制:
版本号机制:
这是乐观锁最常用的一种实现方式,就是在数据库表增加一个数据类型为"version"的字段来实现.
当读取数据的时候,将version字段的值一同读出,数据每更新一次,version的值就加一.当你提交更新的时候,判断数据库表对应的版本version值与第一次取出来的version值进行比对,如果值相同,则允许更新,否则认为是过期的数据.

悲观锁的使用格式:

SELECT…FOR UPDATE


例:select * from db where name=“li” for update

这条 sql 语句锁定了 db 表中所有符合检索条件( name=“li” )的记录。 本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。

格式 SELECT…FOR UPDATE NOWAIT

该关键字的含义是“不用等待,立即返回”,如果当前请求的资源被其他会话锁定时,会发生阻塞,nowait可以避免这一阻塞。

4. 两种锁的使用场景:
乐观锁: 多读写少
悲观锁: 多写读少