Pessimistic and Optimistic locking

事务隔离一般经过锁定任何对事务中资源的访问来实现的。总的来讲,有两种方法针对事务的锁定:乐观锁(Pessimistic locking)和悲观锁(Optimistic locking)数据库

悲观锁(Pessimistic locking)

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其余事务,以及来自外部系统的事务处理)修改持保守态度,所以,在整个数据处理过程当中,将数据处于锁定状态。悲观锁的实现,每每依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,不然,即便在本系统中实现了加锁机制,也没法保证外部系统不会修改数据)。安全

悲观锁的缺点在于,资源第一次的访问就会被事务锁定,除非事务完成,资源始终是不可访问的。若是大量事务都是仅仅对事务进行检索而不是更新操做,那么这种排它锁会大量阻塞,引发锁的争用。这种状况下,乐观锁会是一种更好的方案。在使用悲观锁的状况下,是经过请求失败来保证并发安全性的。以银行系统为例,一旦一个帐户经过事务来访问,那么就会锁定整个帐户。其余的事务尝试访问帐户都会被延迟,阻塞,直到以前的事务结束(完成或者回滚)。悲观锁会一直存在,直到事务提交或者回滚。markdown

乐观锁( Optimistic Locking )

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据通常状况下不会形成冲突,因此在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,若是发现冲突了,则让返回用户错误的信息,让用户决定如何去作。那么咱们如何实现乐观锁呢,通常来讲有如下2种方式:并发

  • 使用数据版本(Version)记录机制实现,这是乐观锁最经常使用的一种实现方式。何谓数据版本?即为数据增长一个版本标识,通常是经过为数据库表增长一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当咱们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,若是数据库表当前版本号与第一次取出来的version值相等,则予以更新,不然认为是过时数据。
  • 乐观锁定的第二种实现方式和第一种差很少,一样是在须要乐观锁控制的table中增长一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version相似,也是在更新提交的时候检查当前数据库中数据的时间戳和本身更新前取到的时间戳进行对比,若是一致则OK,不然就是版本冲突。

在使用乐观锁的时候,资源并不会在第一次由事务访问的时候就锁定,相反,资源的状态会使用悲观锁的方式锁定。当其余事务并发的访问资源,而且访问资源的时候,是可能出现冲突的。当提交的时候,资源将要持久化到存储的时候,会从新读取资源的状态,而后对比事务第一次访问的时候所锁定的状态,若是两个状态不一样,就会有冲突,从而事务会回滚。性能

一样以银行应用为例,帐户第一次由事务访问的时候,就记录了帐户的余额。当事务修改了帐户的余额的时候,帐户的信息会在执行更新以前再次查询帐户的余额。若是余额在事务期间有变化,那么事务就会失败,若是余额没有变化,那么此次修改就会被持久化到存储中。事务

乐观并发控制(Optimistic concurrency control)

乐观并发控制(OCC)是一种应用到事务系统中的并发控制方法,好比在关系数据库管理系统以及软件事务内存等。OCC的理论依据是多数事务在执行更新的时候,是不会影响到彼此的。在运行时,事务使用资源是不须要获取资源的锁的,可是在提交以前,每一个事务都会验证并无其余的事务在修改数据。若是检查碰到了更新冲突,那么事务的提交会回滚,而后从新执行。内存

前面提到了OCC的理论依据,因此OCC通常用于低数据冲突的环境。当争用不多的时候,事务就可以几乎不须要付出管理锁的代价,也不须要等待其余事务完成了。这样能够比其它并发控制带来更高的吞吐。固然了,若是数据资源频繁出现争用的话,那么事务的重启就会严重的影响性能了。这个时候使用其余并发控制可能更好。然而,基于锁的方法(悲观锁)在锁定数据的时候,会严重限制并发性能。资源

相关文章
相关标签/搜索