乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制采用的主要技术手段
无论是悲观锁还是乐观锁,都是定义的概念,可以认为是一种思想,悲观锁正是利用数据库本身提供的锁机制来实现的
详见:http://www.hollischuang.com/archives/934
乐观和悲观锁的简介:
- 悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都会认为被人会修改,所以每次在拿数据的时候都会上锁,这样别人拿这个数据就会block(组织限制),直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁,比如行锁,表锁,读锁,写锁等,都是在操作前先上锁
- 乐观锁:顾名思义,很乐观,每次去拿数据都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间有没有人去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似的write_condition机制的其实都是乐观锁
悲观锁的介绍:
- 悲观锁是一种并发控制的方法,可以阻止一个事务以影响其它用户的方式来修改这个数据,如果一个事务执行的操作在某行应用了锁,那只有当这个事务把锁释放,其它事务才能够执行与该锁冲突的操作
- 主要用于数据竞争激烈的环境 ,以及发生并发冲突时使用锁来保护数据,如果一个事务执行的操作在某行应用了锁,那只有当这个事务把锁释放,其它事务才能够执行与该所冲突的操作
- 悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中加锁机制,也无法保证外部系统不会修改数据)
- 悲观锁一般是用于并发不是很高,并且不允许脏读等情况。但对数据库的资源消耗比较大
悲观锁实现方式:
- 在对任意记录进行修改前,先尝试为该记录加上排他锁(排他锁又称写锁,如果事务T对数据A加上排他锁后,其它事务不能再对A加任何类型的锁,获准排他锁的事务既能读数据,又能修改数据)
- 如果加锁失败,说明该数据正在被修改,那么当前查询可能要等待或者抛出异常。具体响应方式由开发者根据实际需要决定
- 如果加锁成功,那么就可以对该数据进行修改,事务完成后就会解锁
- 期间如果有其他对该记录做修改或者加排他锁的操作,都会等待我们解锁或者直接抛出异常
悲观锁的优缺点:
- 采用先取锁再访问的方式,为数据处理的安全提供了保证
- 会增加额外的开销,增加死锁的机会
- 再只读型事务处理中不会产生冲突,也没必要使用悲观锁
- 降低了并行性,一个事务锁住了某行数据,其它事务就必须等待该事务处理完才能处理
乐观锁介绍:
- 是一种并发控制方法。它假设多用户并发的事务再处理时不会彼此相互影响,各事务能够不产生锁的情况下处理各自影响的那部分数据,在提交数据更新前,每个事务会先检查在该事务读取数据后,有没有其它事务又修改了数据。如果其它事务有更新的话,正在提交的事务会回滚
- 乐观锁在实际应用相对较多,它可以提供更好的并发访问,并且数据库开销较少,但是可能存在脏读的情况
乐观锁的实现方式:
- 一般实现乐观锁的方式就是记录数据
- 当我们提交更新数据的时候,判断数据库表对应记录当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为时过期数据
- 实现数据版本有两种方式,第一种使用版本号,第二种使用时间戳