Mysql里的锁
全局锁
全局读锁: 阻止用户更新数据,但是允许用户读取数据。
全局写锁: 阻止用户读取和更新数据。
开启语句: FILUSH TABLES WITH READ LOCK, UNLOCK TABLES
一般只有迁移数据库才会使用全局锁,用的不多
表锁:
表共享读锁: 当一个事务获得了读锁,其它事务是不能获得该表的写锁,但是能再次获取读锁
表共享写锁: 当一个事务获得了写锁,其他事务是不能获得该表的读锁和写锁的
表锁使用场景:
mysql使用表锁:
SHOW OPEN TABLES WHERE In_use >0; 查看表锁。
#查询进程
show processlist;
#杀死进程(等待锁的)
kill 进程ID;
行锁:
行锁是Mysql中常用的锁定机制,对数据库表中的某一行数据进行锁定,是使用最多的。
行锁优缺点
优点: 锁粒度更小,对事务并发更友好,效率更高
缺点: 对一行进行锁定,相较于表锁,需要更大的内存和cpu资源来保存锁信息
行锁的种类
行锁只会在事务执行期间(commit,rollback执行之前)才会生效,事务执行时会添加行锁,执行完立马释放。
行锁使用场景
行锁上锁时机
行锁的问题
我们来举个行级锁在数据库中的使用:
发现卡死了。
可以看到事务B在等待写锁,lock_status处于wating状态, 只有事务A提交释放锁才能成功修改。
意向锁
当对行进行共享读,Mysql会为全表添加一个意向共享锁(IS)
当对行进行修改时,Mysql会为全表添加一个意向排它锁(IX)
- 在一个事务对一张表的某行添加S锁之前,它必须对该表获取一个IS锁或者优先级更高的锁,然后再添加S锁
- 在一个事务对一张表的某行添加X锁之前,它必须对该表获取一个IX锁。
为什么使用意向锁
当事务A操作表中的某个数据时,事务B来查询全表,需要对表的每一行进行判断,看是否有写锁,这样的话,效率比较低。这个时候如果有一个意向排它锁,事务B看到这个排它锁就不会再去一行行判断是否有写锁,而是直接等待锁。
意向锁可以让事务对全表进行操作的时候可以快速判断是否可以获取锁,而不用扫描每一行。
意向锁冲突情况
什么时候获取锁会发生锁冲突?
下面是官网的图:
下图里面的X与S是指对全表的操作。
IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。
记录锁
记录锁就是为某行记录加锁,它封锁该行的索引记录:
比如使用update ... where id = 1;
注意: 这里的id必须为主键或唯一索引
- id 列必须为唯一索引列或主键列,否则上述语句加的锁就会变成临键锁。
- 同时查询语句必须为精准匹配(=),不能为 >、