正如其名,它指的是对数据被外界(包括本系统当前的其余事务,以及来自外部系统的事务处理)修改持保守态度,所以,在整个数据处理过程当中,将数据处于锁定状态。悲观锁的实现,每每依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,不然,即便在本系统中实现了加锁机制,也没法保证外部系统不会修改数据)。数据库
悲观锁大多数状况下依靠数据库的锁机制实现,以保证操做最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销每每没法承受。
如一个金融系统,当某个操做员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户账户余额),若是采用悲观锁机制,也就意味着整个操做过程当中(从操做员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操做员中途去煮咖啡的时间),数据库记录始终处于加锁状态,能够想见,若是面对几百上千个并发,这样的状况将致使怎样的后果。并发
大可能是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增长一个版本标识,在基于数据库表的版本解决方案中,通常是经过为数据库表增长一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,以后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,若是提交的数据版本号大于数据库表当前版本号,则予以更新,不然认为是过时数据。性能
假设数据库中账户信息表中有一个 version 字段,当前值为 1 ;而当前账户余额字段( balance )为 $100 。spa
1 操做员 A 此时将其读出( version=1 ),并从其账户余额中扣除 $50( $100-$50 )。blog
2 在操做员 A 操做的过程当中,操做员B 也读入此用户信息( version=1 ),并从其账户余额中扣除 $20 ( $100-$20 )。事务
3 操做员 A 完成了修改工做,将数据版本号加一( version=2 ),连同账户扣除后余额( balance=$50 ),提交至数据库更新,此时因为提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。io
4 操做员 B 完成了操做,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操做员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不知足 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略,所以,操做员 B 的提交被驳回。class
这样,就避免了操做员 B 用基于 version=1 的旧数据修改的结果覆盖操做员A 的操做结果的可能。基础