数据库
首页 > 数据库> > 数据库中的锁

数据库中的锁

作者:互联网

1 锁

Java锁和数据库中的锁其实是一样的,
为了避免多个事务同时操作数据库导致数据异常,一般会通过锁机制解决。
加锁是为了避免并发导致数据出现异常,来保证数据一致

image

2-共享锁

在查询语句后面增加
LOCK IN SHARE MODE
,Mysql会对查询结果中的每行都加共享锁。
SELECT ... LOCK IN SHARE MODE;

其他线程也可以读取使
别急,慢慢来。

用了共享锁的表,而且这些线程读取的是同一个版本的数据。
当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。

3 -排他锁

就是我们对数据进行写操作的时候,要先获得写锁,
获得写锁的事务既可以写数据也可以读数 据。

但是如果数据库已经被别人增加了排他写锁,那么后面的事务是无法在获得该数据库的任何锁的。
也就是说,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。
获准排他锁的事务既能读数 据,又能修改数据。

用法
在查询语句后面增加
FOR UPDATE
,Mysql会对查询结果中的每行都加排他锁
SELECT ... FOR UPDATE;
当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

写操作会被默认增加排他锁,不需要显示声明
读操作需要显式声明。

拿MySql的InnoDB引擎来说,对于
insert

update

delete
等操作。会自动给涉及的数据加排他锁;

对于一般的
select
语句,InnoDB不会加任何锁

,事务可以通过以下语句给显示加共享锁或排他锁。

共享锁:

SELECT ... LOCK IN SHARE MODE;

排他锁(悲观锁):

SELECT ... FOR UPDATE;

悲观锁

悲观锁:每次去取数据,很悲观,都觉得会被别人修改,所以在拿数据的时候都会上锁。简言之,共享资源每次都只给一 个线程使用,其他线程阻塞,等第一个线程用完后再把资源转让给其他线程。synchronized和ReentranLock等都是悲观 锁思想的体现。

优点:

悲观锁利用数据库中的锁机制来实现数据变化的顺序执行,这是最有效的办法

缺点:

一个事务用悲观锁对数据加锁之后,其他事务将不能对加锁的数据进行除了查询以外的所有操作,如果该事务执行时间很 长,那么其他事务将一直等待,那势必影响我们系统的吞吐量。

乐观锁

乐观锁:每次去取数据,都很乐观,觉得不会被被人修改。因此每次都不上锁,但是在更新的时候,就会看别人有没有在 这期间去更新这个数据,如果有更新就重新获取,再进行判断,一直循环,直到拿到没有被修改过的数据。 CAS(Compare and Swap 比较并交换)就是乐观锁的一种实现方式。

乐观锁

事务在从数据库中取数据时,会将该数据的版本也取出来(v1),当事务对数据变动完毕想要将其更新到表中时,会将之前取出的 版本v1与数据中最新的版本v2相对比,如果v1=v2,那么说明在数据变动期间,没有其他事务对数据进行修改,此时,就允许 事务对表中的数据进行修改,并且修改时version会加1,以此来表明数据已被变动。

如果,v1不等于v2,那么说明数据变动期间,数据被其他事务改动了,此时不允许数据更新到表中,一般的处理办法是通知用 户让其重新操作。不同于悲观锁,乐观锁是人为控制的。

优点:

乐观锁不在数据库上加锁,任何事务都可以对数据进行操作,在更新时才进行校验,这样就避免了悲观锁造成的吞吐量 下降的劣势。

缺点:

乐观锁因为是通过我们人为实现的,它仅仅适用于我们自己业务中,如果有外来事务插入,那么就可能发生错误。

image

74-乐观锁,悲观锁场景

image

如果悲观锁和乐观锁都可以使用,那么选择就要考虑竞争的激烈程度:
当竞争激烈(出现并发冲突的概率大)时,
悲观锁更有优势,因为乐观锁在执行更新时频繁失败,需要不断重试,浪费CPU资源。

当竞争不激烈 (出现并发冲突的概率小)时,
乐观锁更有优势,
因为悲观锁会锁住代码块或数据,其他线程无法同时访问,影响并 发,
而且加锁和释放锁都需要消耗额外的资源

悲观锁:因为悲观锁会影响系统吞吐的性能,所以适合应用在写为居多的场景下。

乐观锁:因为乐观锁就是为了避免悲观锁的弊端出现的,所以适合应用在读为居多的场景下。

121-几个锁概念

轻量级锁认为,当你在方法里面执行的时候,

其实是很少刚好有人也来执行这个方法的,
所以,当我们进入一个方法的 时候根本就不用加锁,
我们只需要做一个标记就可以了,也就是说,
我们可以用一个变量来记录此时该方法是否有人在 执行。
也就是说,如果这个方法没人在执行,当我们进入这个方法的时候,采用CAS机制,
把这个方法的状态标记为已 经有人在执行,
退出这个方法时,在把这个状态改为了没有人在执行了。

行锁,表锁

image

标签:事务,加锁,数据库,乐观,线程,悲观,数据
来源: https://www.cnblogs.com/hellosiyu/p/15687313.html