数据库锁机制详解

事先声明:本文为原创文章,禁止直接转载和抄袭,若要转载需经过本人同意。

概述

在上篇博文里讲过,锁的种类整体分为java内置锁、数据库锁和分布式锁,上篇博文里解述了 Lock的使用场景和原理,本篇博文笔者将对数据库锁机制进行详解,主要针对数据库锁类型和锁机制进行分析。

数据库锁类型

1、悲观锁
2、乐观锁

数据库锁从概念上讲分为悲观锁和乐观锁,悲观锁是数据库自身的锁机制,乐观锁是通过sql语句实现的,但是乐观锁需要依托于数据库的隔离级别为可重复读。

使用场景

数据库锁的使用场景和Lock锁类似,都是针对临界资源去使用,目的也是为了保证临界资源的安全性,只不过数据库的临界资源是数据库中的数据。

数据库锁分析

悲观锁

悲观锁是数据库锁机制,数据库锁分为表锁、行锁、间隙锁,下面一一介绍这几种锁的使用。

行锁

select * from table where id = 1 for update;
执行以上sql后就会开启行锁。在开启行锁后,当前事务未提交之前,其他事务不可以对该行数据进行操作。行锁会产生阻塞,所以比较耗费资源,粒度较大,会降低并发。

间隙锁

select * from table where id > 1and id <5 for update;
执行以上sql后就会开启间隙锁。间隙锁和行锁的不同之处就是间隙锁会占有范围内的资源,如上述sql,间隙锁会占有小于5且大于1的数据。同样,间隙所也会产生阻塞,但是其粒度比行锁更大。

表锁

lock tables table read;(读锁)
lock tables table write;(写锁)
unlock tables;(解锁)
执行以上sql任意之一就可以开启表锁,但是需要注意的是表锁分为读锁和写锁。如果执行第一行sql则会开启读锁,如果执行第二句sql则会开启写锁。读锁和写锁的区别就是,读锁不会阻塞读操作,只会阻塞写操作,而写锁则无论读操作还是写操作都会阻塞。表锁会锁住整张表,表里的数据都会产生阻塞,表锁粒度最大,并发最低。

临键锁

这里提一个临键锁的概念,数据库锁是加在索引上的,如果锁的作用字段是一个非索引字段,那么行锁可能会升级为表锁

乐观锁

乐观锁是sql的一种写法,它依赖于数据库的隔离级别为可重复读,下面做具体分析:
在使用乐观锁时,一般会有一个version字段来记录版本,在每次更新操作之前,先将version版本号查询出来,在更新数据时,以version版本号作为条件去更新,这样就可以保证当前事务所更新的数据是未被其他事务更新的,sql如下:

首先查询版本号:select version from table where id = 1;(假设查询到的version为1)
更新数据:update table set xx = xx, version = version + 1 where id = 1 and version = 1;

这就是乐观锁的sql写法,那么看到这里是否有个疑问,为什么这样写就可以实现乐观锁呢?还有上文之前提到的乐观锁依赖于数据库事务又是怎么回事呢?

分析乐观锁原理:

1、假设现有一张表table,有三个字段:id、status、version,其中version是版本字段。
2、表里有一行数据:id = 1、status = 0、version = 1。
3、现在有两个事务,事务A和事务B要对该行数据同事做出修改。
4、在修改该行数据之前,事务A先查询到version = 1,事务B也先查询到version = 1。
5、执行修改sql:
事务A:update table set status = 1,version = version +1 where id = 1 and version = 1;
事务B:update table set status = 2,version = version +1 where id = 1 and version = 1;
6、提交事务,假设A事务先于B事务提交,那么在A事务提交完事务后,version字段在表中的数据已经更新为2。而这时,B事务在A事务之后提交,因为version字段已经变为2,所以B事务更新失败。(这里B事务为什么会更新失败,就涉及到了事物的隔离级别)
以上就是乐观锁的原理。

总结

到这里,数据库锁的使用场景以及原理机制详解就讲完了,若是对文章中的一些点有疑惑,可在评论区留言或私信我。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值