作者:wolf鬼刀
前言
文章目录
乐观锁悲观锁自旋锁一、悲观锁二、乐观锁1.乐观锁常见的两种实现方式2.版本号机制3.CAS算法4.CAS缺点四、乐观锁和悲观锁的使用场景五、自选锁1.自选锁的原理2.自选锁的缺陷3.自旋锁的使用场景
一、悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
二、乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。
1.乐观锁常见的两种实现方式
2.版本号机制
一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数。当数据被修改时,version值会加1。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
举一个简单的例子:
1.假设数据库中帐户信息表中有一个versionversionversion字段,当前值为;而当前帐户余额字段(balancebalancebalance)为
2.当需要对账户信息表进行更新的时候,需要首先读取version字段。
3.操作员AAA此时将其读出(version=1version=1version=1),并从其帐户余额中扣除.当需要对账户信息表进行更新的时候,需要首先读取version字段。3.操作员AAA此时将其读出(version=1version=1version=1),并从其帐户余额中扣除50(
50)。
在操作员AAA操作的过程中,操作员BBB也读入此用户信息(version=1version=1version=1),并从其帐户余额中扣除
-
balance=),提交至数据库更新,6.此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录versionversionversion更新为。操作员BBB7.完成了操作,提交更新之前会先看数据库的版本和自己读取到的版本是否一致,但此时比对数据库记录版本时发现,操作员BBB提交的数据版本号为,而自己读取到的版本号为,不满足“当前最后更新的versionversionversion与操作员第一次读取的版本号相等“的乐观锁策略,因此,操作员B的提交被驳回。8.这样,就避免了操作员BBB用基于version=1version=1version=1的旧数据修改的结果覆盖操作员A的操作结果的可能。3.CAS算法
即
转载请注明:http://www.0431gb208.com/sjslczl/5336.html