乐观锁和悲观锁

来源:互联网 发布:佳能软件下载 编辑:程序博客网 时间:2024/06/05 03:14

1.起因

  突然想起来的是很早一次面试的时候,面试官问我,你知不知道乐观锁和悲观锁的含义,当时没有复习到那里,只是依稀记得悲观锁是for update,这个给躺了,在这里记录一下。

2.含义

  悲观锁,正如其名,具有强烈的独占和排他特性。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
  乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库 性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。相对悲观锁而言,乐观锁更倾向于开发运用。
  上面的解释是度娘专供,其实总结一下就是:悲观嘛,在自己操作数据库的时候,总是认为有人会和他一起进行操作数据库,所以只要我操作数据库,我就把数据库进行上锁,等我操作完释放锁之后,其他的关于这个记录操作才能进行操作;乐观嘛,就是认为自己操作的时候不会有其他人的操作,但是每次更新操作的时候,都会对应一下是不是自己的版本即version;

3 悲观锁

  悲观锁以mysql为例子,mysql 是自动进行提交事务的所以在测试之前要设置一下,set autocomment = 1;
  话不多说上图:
这里写图片描述

  这个是开启事务,然后使用for update 将这条记录进行加锁,如果这个是有索引的就是锁这条记录,如果没有索引则是锁整个表。
  然后我们开启另外一个用户进行模拟处理事务,但是不能处理,而是在锁的外面进行等待,但不是长时间的等待,超过时间就会报出异常。
  这里写图片描述
  这个就是报出lock wait timeout exceeded;try restarting transaction 的异常,这只是对更新操作而言,对于查找而言是没有问题的。当我把第一个端口的事务给commit掉的时候,这个便可以执行了。

4 乐观锁

  这个简单说一下,就是根据版本号,进行更新的,列如update user set email = XXXX@XX.com where version = ${version}的时候, 这个版本的样子。不能修改则进行回滚,重新开始。

5 总结

  这之前说的实现都是数据库的实现,悲观锁和乐观锁是一种思想在不同的数据库有不同的处理方式,我是以mysql 为基准的。 这个里面 乐观锁 适合在并发的不太高的要求下可以进行,而悲观锁的锁住记录,有较高的保证率,取舍还是要看实际开发啦。

原创粉丝点击