类似于postgresql的咨询锁,MySQL也有用户级锁函数,是一个比较有意思的东西,之前都没有注意过。
优点:其特点是使用起来更加灵活与个性,相比MySQL隐式的行级锁不同,用户级锁函数使用的可控性更强,可以个性化指定“锁的名称”和锁的过期时间,以及探测锁的可用性等。
缺点:与传统的隐式锁不同的是,显式锁需要用户显式加锁与解锁,并且该类所也不会随着事务的提交或者回滚而释放,需要显式释放,与此同时,可能会对MySQL的复制产生一定的副作用。
以下翻译自官方文档:https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html
本节描述用于操作用户级锁函数。
Table 12.19 Locking Functions
str名称的锁,超时时间为超时。超时时间值代表无秒时间。锁是他的。通过一个会话持有时间,其他会话无法获得同名锁。
1,如果发生尝试超时(例如,因为另一个客户先前已锁定名称),则返回0,如果错误(例如内存不足或线程被mysqladmin kill NULL ?
GET_LOCK() RELEASE_LOCK() GET_LOCK() 获得的锁。
GET_LOCK() (MDL) GET_LOCK() 不会释放任何现有的锁。
SELECT GET_LOCK('lock1',10); SELECT GET_LOCK('lock2',10); SELECT RELEASE_LOCK('lock2'); SELECT RELEASE_LOCK('lock1');
一个给定的会话甚至有可能获得同名的多个锁。其他会话无法获得该名称的锁,直到该会话释放该名称的所有锁。
使用GET_LOCK() 获取唯一的特定锁出现在Performance Schema metadata_locks 表中。OBJECT_TYPE 列表示USER LEVEL LOCK,OBJECT_NAME 列表示锁定名称。
一个锁会在metadata_locks表中注册一行。名称的锁会增加锁中的启动,但不会获得额外的元数据锁。当名称上的最后一个锁实例被释放时,锁的metadata_locks行被删除。
获取多个锁的可能潜在客户端之间出现死锁的事件。假设出现这种情况时,服务器会选择一个调用者并以ER_USER_LOCK_DEADLOCK错误终止其锁定获取请求。此错误不会导致事件回滚。
MySQL对64个字符的锁名称强制执行最大长度。
GET_LOCK() 可用于实现应用程序锁或模拟记录锁。名称在服务器范围内被锁定。如果某个名称在同一个会话中被锁定,则GET_LOCK() 会用于实现应用程序锁或模拟记录锁定。
请求。锁定该方法名称。避免这种对象的一种方法是使用特定于或特定于应用程序的锁名称。例如,使用db_name.str 或app_name.str 形式的锁名称。
如果某些客户端正在等待锁,则它们获取锁的顺序是必然的。
GET_LOCK() 对于基于语句的是不安全的。
警告
有了获取多个命名锁的能力,单个语句就可以获取大量的锁。例如:
INSERT INTO ... SELECT GET_LOCK(t1.col_name) FROM t1;
这些类型的语句可能会产生某些不利影响。例如,如果语句中途失败并回滚,则获取到故障点的锁仍然存在。如果意图是在插入的行和获取的锁之间存在对应关系,则不满足该意图。
此外,如果按特定顺序授予锁很重要,请注意结果集顺序可能会因优化器选择的执行计划而异。由于这些原因,最好将应用程序限制为每个语句的单个锁获取调用。
不同的锁定接口可用作插件服务或一组可加载函数。与GET_LOCK() 和相关函数提供的接口不同,该接口提供锁命名空间和不同的读写锁。有关详细信息,请参阅第5.6.9.1 节,“锁定服务”
检查名为str 的锁是否可以使用(即未锁定)。如果锁空闲(没有人使用锁),则返回1,如果锁正在使用,则返回0,如果发生错误(例如不正确的参数),则返回NULL。
此函数对于基于语句的复制是不安全的。如果在binlog_format 设置为STATEMENT 时使用此函数,则会记录警告。
检查名为str 的锁是否正在使用中(即锁定)。如果是,则返回持有锁的客户端会话的连接标识符。否则,它返回NULL。
此函数对于基于语句的复制是不安全的。如果在binlog_format 设置为STATEMENT 时使用此函数,则会记录警告。
释放当前会话持有的所有命名锁并返回释放的锁数(如果没有,则为0)
此函数对于基于语句的复制是不安全的。如果在binlog_format 设置为STATEMENT 时使用此函数,则会记录警告。
释放由GET_LOCK() 获得的字符串str 命名的锁。如果锁已被释放,则返回1,如果此线程未建立锁(在这种情况下未释放锁),则返回0,如果指定的锁不存在,则返回NULL。如果它从未通过调用GET_LOCK() 获得或先前已被释放,则该锁不存在。
DO 语句与RELEASE_LOCK() 一起使用很方便。见第13.2.3 节,“DO 声明”。
此函数对于基于语句的复制是不安全的。如果在binlog_format 设置为STATEMENT 时使用此函数,则会记录警告。