2023-09-01 数据库-并发控制-使用锁-思考

摘要:

使用锁来控制并发, 既熟悉,又陌生。锁的使用再熟悉不过了,用锁来控制并发就像用锁来处理多线程的安全性问题一样,mysql/innodb的所谓x锁/s锁/间隙锁等等以及什么时候锁表什么时候又是行锁又是八股文里的常客。很难对利用锁来做并发控制不产生一种他乡遇知音的熟悉感。

但是这只是肤浅的表面认知,仅仅是流于表面,对并发控制以及使用锁来进行并发并没有深刻的以及系统化的思考。

本文对利用锁进行并发控制做一些思考。

上下文参考: 2023-08-30 数据库-并发控制-冲突可串行化调度-是否可串行化检测-优先图-分析_财阀悟世的博客-CSDN博客

对于锁的理解:

  1. 锁是什么? 这个问题要是深入的想想,很奇怪对不对,硬件层面只有中断,没有线程和锁的硬件层面的组成!线程和锁是操作系统抽象出来的
    1. linux中对于线程和进程都是task,也就是调度的一个单元, 区别在于内存可见性, 同一个进程的线程共享堆空间, 但是进程间地址空间完全隔离
    2. 这里就引发出进程间通信和线程间通信,进程间通信一般是网络socket, 共享内存,消息队列,父子进程间的copy on write. 例如redis的后台持久化就是创建一个子进程
    3. 线程间的通信一般是叫做线程安全, 由于进程的内存直接可见, 所以直接通信,但是这里就存在多个线程并发执行,线程可访问到对方线程的数据, 导致互相影响
    4. 为了控制临界区,搞出了锁这个概念
  2. 那么锁是什么?
    1. 直白点说,锁其实是个全局的变量, 每个线程都能访问到
    2. 持有锁, 换句话说,就是修改这个变量。检测是否可以获取锁, 其实就是判断这个变量是否已经被修改过, 如果被修改过, 那么就是被其他线程持有了, 本线程只能等待.
    3. 所以这就可以理解了,锁是个变量,来控制线程是否能继续往下执行, 也就是所谓的临界区, 处于等待状态的线程, 不断的周期性的判断变量的值, 以此来作为锁是否已经被其他线程释放,可以被本线程持有
  3. linux中的线程实现pthread是一个在应用层的类库, 是用户态的概念, 所谓的互斥锁mutex,读写锁,信号量等等是在用户态实现
  4. 无锁队列是什么? 什么叫无锁? 其实就是使用CAS来在用户程序内部来实现比较和修改这种原子逻辑, 如果compare不符合预期那么就用个while继续比较判断, 类似于原子锁, 这样线程就不陷入睡眠状态, 看起来就无锁了

用锁来做并发控制:

  1. 第一个也是最重要的问题, 锁究竟是为了保护什么? 肤浅的回答是为了保护临界区, 但是临界区又是什么?
  2. 是的, 锁真正所要保护的, 是数据!是对数据的变化, 也就是写/修改数据, 因为只有写会导致其他线程对数据读取失效,锁保护的是数据,而不是行为
  3. 那么在数据库领域, 数据是什么? 说数据容易引起误解, 一般称呼为数据库资源
  4. 那么数据库的资源又是什么? 保护的是什么? 如果将表理解为资源的单元,那么就是表锁;如果将行理解为资源的单元,那么就是行锁;如果将磁盘块和数据页当作资源的单元,那么就是页锁;
  5. 和事物结合起来, 事物其实可以理解成对资源进行读和写操作的序列, 那么锁是对资源的保护, 那么在修改资源前, 就要加锁, 修改资源后,就要释放锁

利用锁做并发控制的原则:

不但要考虑锁的使用原则,也要考虑事物调度本身的特性

一. 事物的一致性

  1. 持有锁的线程, 负责释放锁
  2. 如果一个事物要修改某些数据, 必须要在修改数据前加锁,在修改数据后解锁

二.调度的合法性

  1. 锁必须具有语义,两个事物不能同时对同一个数据库资源加锁
  2. 也就是说,一个事物要将获得对某个数据库资源的修改,那么必须等待其他事物先释放锁

利用锁进行并发控制的抽象动作计法:

  1. 如果一个没加锁的事物是:T=R(A),W(A),R(B),W(B),R(B)
  2. 那么设定加锁的符号为l,解锁的符号为u
  3. 进行加锁则为: T = L(A), R(A), W(A), U(A), L(B), R(B), W(B), R(B), U(B)
相关推荐
IT古董4 小时前
《FDE前沿部署工程师实战教程》33 - Enterprise AI Observability:从Agent Trace到全链路智能运维
数据库·人工智能
for_ever_love__5 小时前
MySQL 主从复制讲透:binlog 原理、搭建步骤与读写分离
java·数据库·mysql·binlog·读写分离·原理·主从复制
Nturmoils9 小时前
GROUP BY 先别想当然,查汇总前把规则跑清楚
数据库
最笨的羊羊9 小时前
Oceanbase数据库系列之:向量数据库核心知识
数据库·oceanbase
fish_xk9 小时前
mysql中的表的约束
数据库·mysql
谢亮_vipxieliang9 小时前
Go Channel 高级模式——从底层原理到扇出扇入实战
java·数据库·golang
ggaofeng11 小时前
自己编写邮件服务器和客户端
数据库
java1234_小锋11 小时前
【技术专题】Mysql8 数据库 - Mysql8 添加,更新,删除数据
数据库·mysql
PaperData11 小时前
2015-2024年各省绿色贸易数据
数据库
小羊没烦恼!11 小时前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#