Mysql 锁
mysql锁的类型
- 表锁
- 行锁
表锁和行锁都有的种类
1 | 共享锁(shared lock),也叫读锁(read lock) |
结论:
1 | 读锁会阻塞写操作,不会阻塞读操作 |
表锁实现的锁机制
表锁实现的效果:
- 共享锁:锁住整个表,可读取表数据但是不能操作表中的数据,必须等锁释放后才能操作表中的数据
- 排他锁:锁住整个表,不可读取表数据和操作表数据,必须等锁释放后才能读取或操作表中的数据
表锁的优点:
- 对整张表加锁
- 开销小
- 加锁快
- 无死锁
- 锁粒度大,发生锁冲突概率大,并发性低
行锁实现的锁机制
行锁实现的效果:
- 共享锁:锁住操作的数据,可读取数据但是不能操作数据,必须等锁释放后才能操作数据
- 排他锁:锁住操作的数据,不可读取数据和操作数据,必须等锁释放后才能读取或操作数据
行锁的优点
- 对一行数据加锁
- 开销大
- 加锁慢
- 会出现死锁
- 锁粒度小,发生锁冲突概率最低,并发性高
mysql上锁命令
表锁:
隐式上锁(默认,自动加锁自动释放)
1 | select #默认上共享锁 |
1 | insert、update、delete #上排他锁 |
显式上锁(手动)
1 | lock table tableName read; #共享锁 |
解锁(手动)
1 | unlock tables; # 解锁所有表 |
行锁:
隐式上锁(默认,自动加锁自动释放)
1 | select #不上锁 |
1 | insert、update、delete #上排他锁 |
显式上锁(手动)
1 | select * from tableName where id = xxx in share lock; #共享锁 |
解锁(手动)
1 | 1. 提交事务(commit) |
1 | 为什么上了写锁,别的事务还可以读操作? |
死锁
什么是死锁?
1 | 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 |
通俗来讲就是a锁持有数据a,b锁持有数据b,他们同时都在请求对方的数据,但是因为双方都有锁所以进入互相等待状态
产生死锁的四个必要条件
1 | (1)互斥条件:该资源任意时刻只由一个线程占有 |
避免死锁
1 | 1. 加锁顺序一致,尽可能一次性锁定所需的数据行 |
悲观锁和乐观锁
悲观锁
1 | 总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加(悲观)锁。一旦加锁,不同线程同时执行时,只能有一个线程执行,其他的线程在入口处等待,直到锁被释放。 |
行锁和表锁就属于悲观锁
乐观锁
1 | 乐观锁顾名思义就是在操作时很乐观,认为操作不会产生并发问题(不会有其他线程对数据进行修改),因此不会上锁。但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS(compare and swap)算法实现。 |
参考文章:
https://learnku.com/articles/39212?order_by=vote_count&
https://segmentfault.com/a/1190000016611415
https://blog.csdn.net/greenfloweryue/article/details/107846958