本文介绍了关于“如何理解Java悲观锁和乐观锁”的知识。很多人在实际案例操作中都会遇到这样的困难。接下来,让边肖带领大家学习如何应对这些情况!希望大家认真阅读,学点东西!
一个
锁
在介绍悲观锁和乐观锁之前,我们先来看看什么是锁。
锁在我们的生活中随处可见。我们的门上有锁,我们存钱的保险箱上也有锁,用来保护我们的财产。
程序中也有锁。当多个线程修改一个共享变量时,我们可以同步修改操作。
当多个用户修改表中相同的数据时,我们可以锁定数据的行(行锁)。因此,锁实际上控制了并发下多个操作的顺序执行,从而保证了数据安全性的变化。
而且,锁是一种保证数据安全的机制和手段,并不特定于某一种技术。悲观锁和乐观锁也是如此。本文介绍的悲观锁和乐观锁都是基于数据库级别的。
2
悲观锁
悲观并发控制,乍一看,相信大家都会认为是悲观锁。是的,它是一把悲观的锁。
这种悲观情绪体现在哪里?悲观主义是人类的一种负面情绪,与洛克的悲观主义相对应。悲观锁认为其保护的数据极其不安全,可能会一直变化。事务获得悲观锁(可以理解为用户)后,其他事务都不能修改数据,只能执行到锁被释放。
数据库中的行锁、表锁、读锁、写锁以及同步实现的锁都是悲观锁。
在这里,我们再来介绍一下数据库的表锁和行锁,以免部分同学理解悲观锁的实现。
我们常用的数据库是mysql,mysql中最常用的引擎是Innodb,默认使用行锁。行锁是基于索引的,所以如果要添加行锁,就必须在锁的时候命中索引,否则就会使用表锁。
三
乐观锁定
与悲观相对应,乐观是人类的一种积极情绪。乐观锁定的“乐观”体现在它相信数据不会变化太频繁。因此,它允许多个事务同时更改数据。
但是,乐观并不意味着不负责任,那么如何负责多个事务序列修改数据呢?
乐观锁定通常通过向表中添加版本或时间戳来实现,其中版本是最常用的版本。
当事务从数据库中检索数据时,它也将检索数据的版本(v1)。当事务更改数据并希望将其更新到表中时,它会将先前检索到的版本v1与数据中的最新版本v2进行比较。如果v1=v2,则意味着在数据更改期间,没有其他事务会修改数据。此时,允许事务修改表中的数据,版本将增加1,表示数据已被修改。
如果v1不等于v2,则意味着在数据更改期间,数据被其他事务更改。此时,不允许将数据更新到表中。一般的解决办法是通知用户重新操作。与悲观锁不同,乐观锁是人为控制的。
四
如何实施
通过以上研究,我们知道悲观锁和乐观锁是用来控制并发数据的顺序变化的。然后我们模拟一个需要加锁的场景,看看不加锁会发生什么,以及如何使用悲观锁和乐观锁来解决。
场景:用户A和B最近都想吃猪肉干,于是打开购物网站,发现是同一家店在卖猪肉干。以下是本店商品表的结构和表中的数据。
从表中可以看出,目前只有一个猪肉干。没有锁定,如果A和B同时下单,可能会导致超卖。
悲观锁定解决方案
使用悲观锁的解决思路是,我们认为数据修改冲突的概率比较高,所以在更新之前,我们表明应该锁定要修改的记录并释放锁,直到完成修改。锁定时只有自己可以读写,其他事务只能读不能写。
a .下单前给猪肉干的数据(id=1)添加悲观锁(行锁)。这时候,这一行数据只能由A来操作,也就是只有A才能买。如果你想买,你必须一直等下去。
A买的时候,B想再买的时候,会发现数量已经是0了,那么B看到之后就会放弃买。
那么如何给猪肉干的数据增加一个悲观锁,也就是id=1?我们可以通过以下语句向id=1的数据行添加悲观锁
selectnumrfomgoodsheid=1 for update;这里介绍一下“如何理解Java悲观锁和乐观锁”的内容。感谢您的阅读。如果你想了解更多的行业,可以关注网站。边肖将为您输出更多高质量的实用文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/102529.html