博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

悲观锁,乐观锁

Posted on 2019-06-14 11:58  老鼠蟒蛇  阅读(188)  评论(0编辑  收藏  举报

乐观锁与悲观锁

北京这两天天气不好,时晴时阴,最近有有点累,所以在家里休息了两天,看了一下乐观锁与悲观锁,虽然没有茅塞顿开,但是也有点收获。

先想一想为什么要使用锁?

在用户访问你的网站时,同一时间可能会有多个用户更新相同的记录,这时候他们同时访问数据库,这就会产生冲突,这就是著名的并发(高并发)。

高并发会产生什么后果呢?

丢失更新:一个事务的更新覆盖了其他事务的更新,这就是所谓的更新丢失。列如管理员A把数据库中的2改成了6,管理员B把值从6又改成了2,这个时候,用户A就丢失了他的更新。

脏读 :当一个事务读取其他完成一半事务的记录时,就会发生脏读,列如:管理员AB读取数据库时看到的都是6 ,用户B把值改为2,用户A读取到的值仍是6 .

超卖: 如果maysql中没有锁的存在的话,他会产生超卖的情况,你库存只有十个,但是一百个用户同时去访问你的数据库,这时候就会产生超卖。可能你就会卖出12件商品。

解决高并发的方法:

  • 悲观锁: 假设会发生并发冲突,屏蔽一切可能违反数据完整性的操作, 认为会多人操作同一条数据,因此操作数据时直接把数据锁住,直到一个人操作完成后才会释放锁;上锁期间其他人不能修改数据。
  • 乐观锁: 假设不会发生并发冲突,只在操作时检查是否违反数据完整性,如果别人修改了数据则放弃操作,否则执行操作。而乐观锁不能解决脏读,因为他在操作时才会去检查,而脏读是在操作中产生的。
  • 版本号机制:  MySql最经常使用的乐观锁时进行版本控制,也就是在数据库表中增加一列,记为version,当我们将数据读出时,将版本号一并读出,当数据进行更新时,会对这个版本号进行加1,当我们提交数据时,会判断数据库表中当前的version列值和当时读出的version是否相同,若相同说明没有进行更新的操作,不然,则取消这次的操作

总结::在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法.