锁是计算机在执行多线程或线程时用于并发访问同一共享资源时的同步机制,MySQL中的锁是在服务器层或者存储引擎层实现的,保证了数据访问的一致性与有效性。
MySQL锁可以按模式分类为:乐观锁与悲观锁。
按粒度分可以分为全局锁、表级锁、页级锁、行级锁。
按属性可以分为:共享锁、排它锁。
按状态分为:意向共享锁、意向排它锁。
按算法分为:间隙锁、临键锁、记录锁。
1、全局锁:锁定数据库中的所有表。
语法:
加全局锁
flush tables with read lock ;
释放锁
unlock tables ;
特点:
如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。
如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志( binlog ),会导
致主从延迟。
在 InnoDB 引擎中,我们可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致
性数据备份。
2、表级锁:每次操作锁住整张表。
语法:
加锁: lock tables 表名 ... read/write 。
释放锁: unlock tables / 客户端断开连接 。
特点:
读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞
其他客户端的写。
3、行级锁:每次操作锁住对应的行数据。
类型:
共享锁:
共享锁,又称之为读锁,简称S锁,当事务A对数据加上读锁后,其他事务只能对该数据加读锁,不能做任何修改操作,也就是不能添加写锁。只有当事务A上的读锁被释放后,其他事务才能对其添加写锁。
排它锁:
排它锁,又称之为写锁,简称X锁,当事务对数据加上写锁后,其他事务既不能对该数据添加读写,也不能对该数据添加写锁,写锁与其他锁都是互斥的。只有当前数据写锁被释放后,其他事务才能对其添加写锁或者是读锁。
MySQL InnoDB引擎默认update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型。
语法:
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE
释放锁:commit
适用场景
1、共享锁适用于:用来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作,如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁。
2、排他锁适用于:锁定行记录后需要进行更新操作的应用。