之前面试的时候问到了我这这个问题,奈何并没有说出个所以然,所以今天就在网上查找相关的资料,发现了一篇写的非常好的文章,思路很清晰,介绍的也很细致,易懂,链接如下:https://www.jianshu.com/p/d2ac26ca6525
我后文对悲观锁和乐观锁的理解基本上都来自这篇文章,也引用了很多这篇文章里的东西,之所以接着写这后面的内容,是为了自己能记得更牢固,所以如果有人看到了我这篇博客,直接移步去链接就好啦
引入
我们在平时编写程序的时候,会碰到需要用到多线程的时候,而这个时候往往就需要我们做到并发控制,也就是通过并发控制来确保我们的数据是准确的,不会因为线程的推进顺序等原因而产生数据错误的情况。
图片来源于链接文章
而我们要实现并发控制就可以通过悲观控制和乐观控制这两种机制,也就是我们说的悲观锁和乐观锁。
悲观锁
悲观锁,其实顾名思义,就是我们对并发修改数据导致错误持一个悲观的态度,那么当我们需要对数据库里的一条数据进行修改的时候,就会先将该条数据锁定,防止其他线程同时也对该数据进行修改造成数据的错误,只有当我们修改完毕,释放锁以后,其他线程才能对该条数据进行修改。
悲观锁的实现借助了数据库的锁机制,在修改前先锁定再修改。具有强烈的独占性和排他性。
悲观锁有主要分为两类:共享锁和排它锁
- 共享锁
其实从名字来看,既然是共享,那么就证明多个事务可以共享同一把锁,而要实现并发控制,该情况只能是对于不修改数据的情况,也就是只读的情况,所以共享锁又称为读锁。
即多个事务都是访问到数据,但是只能读,不能修改数据。 - 排它锁
对于排它锁来说,简言之就是数据只能由获得排它锁的那个事务访问,而之所以要求会这么高,无疑是因为他要对数据进行修改,只有数据修改完以后才能释放排它锁,所以,排它锁又称写锁。
即事务获取到排它锁以后,其他的事务不能对该数据进行访问或修改。
从以上的介绍,可以很容易看出悲观锁降低了并行性,并且在效率方面也有一定的影响,还有可能会造成死锁的情况。
乐观锁
乐观锁即是对数据冲突的情况持一个乐观的态度,他只有在对数据进行更新的时候才会检测是否会造成冲突,如果造成了冲突,会将信息返回给用户,由用户自己决定。
乐观锁并不使用数据库的锁机制,它一般是通过记录数据的版本来实现的。但是这样的实现就注定如果有多个事务想对同一条数据进行修改,那么只有一个事务能够成功,其他的都会返回失败,所以虽然乐观锁的效率较高,但当锁的粒度没有掌握好,会很容易导致业务失败,影响用户的使用体验。