基本概念
锁是一种协调多个事务对同一数据并发访问的一种机制。它确保了数据库的一致性和完整性,防止多个事务同时修改一份数据导致冲突。
锁的类型
锁分为全局锁、表级锁、行级锁。全局锁会锁定整个数据库实例,使其处于只读状态;表级锁会在执行操作时锁定整张表;行级锁会锁住相关行的数据。注意!表级锁、行级锁不一定会让对应的表或者数据行处于只读状态,这得取决于锁的模式。
锁的模式
锁具有排他锁、共享锁两种模式。共享锁:允许多个事务同时读取数据,是数据库管理系统实现并发控制的一种机制,但是数据被读取期间,事务不能对数据进行修改,这种锁通常用于实现事务的可重复读(repeatable read)隔离级别。确保一个事务可以多次读取到同样的数据而不被其它事务的修改所影响;排他锁:当前事务仍具有该表的增删改查权限,其它事务将无法对该表进行增删改查操作。这种锁通常用于写操作,确保数据的一致性和完整性。
锁的创建与释放
创建一个全局锁:flush tables with read lock;
在对应的数据库执行该命令之后,该库下所有的表都会处于只读模式,无法修改、删除数据。解除全局锁:unlock tables;
通常在数据库整库维护的时候,会使用该锁。
创建一个表级锁,表级锁创建有共享锁、排他锁两种模式。创建一个表级的共享锁:lock tables table_name read;
创建共享锁之后,在当前事务中可以对表数据进行查询操作,但不能进行增删改操作;其他事务也能进行查询操作,但不能进行增删改操作;创建一个表级排他锁:lock tables table_name write;
在当前事务创建一个排他锁之后,当前事务仍具有该表的增删改查权限,其它事务将无法对该表进行增删改查操作,必须等待当前事务完成并且锁被释放,其它事务才能对该表进行增删改查。(当前会话可以开启多个事务,如果当前会话不开启事务,会隐式的开启事务,会话不变,所有的操作均在当前事务进行)释放表级锁:unlock tables;
创建一个行级锁,行级锁的创建也分为共享锁、排他锁两种模式。创建一个行级共享锁:select * from table_name where cloum_name = "xxx" lock in share mode;
创建完成之后,只允许当前事务以及其它事务读取该行的信息,不允许修改;创建一个行级排他锁:select * from table_name where cloum_name = "xxx" for update;
注意!创建行级锁时,对应的字段上要有索引;行级的排他锁创建之后,当前事务具有该行的读、写权限;其它事务无写权限,并且读取到该行的内容是第一个事务提交前的内容,会出现脏读。后续的修改内容无法获取。这跟数据库的多版本并发机制有关(原理为:通过保存数据的历史版本来实现事务的隔离性)。
锁的优缺点
【优点】
1.保证数据一致性:正确的使用锁能够确保在并发环境下,事务对数据的修改能够保持一致性。防止多个事务同时修改数据造成数据冲突。
2.提高系统并发性能:锁的存在,允许多个事务并发执行,能够提高系统的吞吐量。
3.支持事务隔离性:锁为事务提供了隔离性,使得每个事务能够在独立的环境中允许,从而保证了事务的正确性和可靠性。
4.确保系统稳定运行:合理的使用锁策略。可以减少或避免死锁的发生,确保系统稳定
【缺点】
1.降低并发性能:过度使用锁可能导致系统并发性下降
2.可能导致死锁:事务在获取锁时没有合理的顺序或未能及时释放锁,可能会导致死锁,即多个事务互相等待对方释放锁而无法继续执行。
3.增加系统复杂性:引入锁机制会增加系统的复杂性,需要更多的资源来管理和维护锁,同时也增加了程序设计的复杂性。
锁与隔离级别的关系
1.读未提交(Read Uncommitted):这是最低的隔离级别,它允许事务读取尚未提交的更改。在这个级别上,不会使用行级锁,因为读操作不需要等待其他事务释放锁。这可能导致脏读,即读取到其他事务未提交的数据。
2.读已提交(Read Committed):在该级别下,事务只会读取已经提交的数据。当一个事务开始读取数据时,它会获得一个共享锁,一旦读取完成,该锁就会被释放。这个级别的锁主要是为了解决脏读问题。
3.重复读(Repeatable Read):这是MySQL的默认隔离级别。它确保在一个事务的整个过程中可以重复读取同一行数据,并且看到相同的值,即使其他事务已经修改了这些数据。在这个级别上,事务会在读取数据时使用排他锁,直到事务结束。这种锁防止了脏读和不可重复读的问题。----跟MySQL的mvcc机制有关
4.序列化(Serializable):这是最高的隔离级别,它完全隔离事务,使得每个事务都像是在单独执行一样。在这个级别上,事务会对读取的所有行加上锁,无论是共享锁还是排他锁,并且会使用范围锁来保护一系列值不被其他事务修改。
注意!对于任何隔离级别,表级别的锁都会被使用。
学海无涯