暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL的函数和运算符 - 锁函数

林员外聊编程 2021-07-28
566
锁函数
 
本部分介绍用于操作用户级锁的函数。
 
名称
介绍
GET_LOCK()
获得一个命名锁
IS_FREE_LOCK()
命名锁是否释放
IS_USED_LOCK()
指定的锁是否正在使用,如果为真,返回连接标识符
RELEASE_ALL_LOCKS()
释放当前所有命名锁
RELEASE_LOCK()
释放命名锁
 
● GET_LOCK(str,timeout)
 
尝试获取名称为字符串 str 的锁,指定超时时间为 timeout 秒。timeout 为负数表示无限超时。锁是独占的。当被一个会话持有时,其他会话不能获得同名的锁。
 
如果成功获得了锁,则返回 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() 获得第二个锁,两个 RELEASE_LOCK() 调用都返回 1(成功)
 
对于给定的会话,甚至有可能获得同名的多个锁。其他会话不能获取此同名的锁,直到获取的会话释放其同名的所有锁。
 
GET_LOCK() 获得的唯一命名的锁出现在 Performance Schema metadata_locks 表中。OBJECT_TYPE 列值为 USER LEVEL LOCKOBJECT_NAME 列表示锁名。如果多个锁获取同一名称,则只有该名称的第一个锁在 metadata_locks 表中注册一行。该名称的后续锁将增加锁中的计数器,但不会获得额外的元数据锁。当释放该名称上的最后一个锁实例时,锁对应的 metadata_locks 行将被删除。
 
获得多个锁的能力意味着在客户端之间存在死锁的可能性。当发生这种情况时,服务器选择一个调用者,并以 ER_USER_LOCK_DEADLOCK 错误终止其获取锁的请求。此错误不会导致事务回滚。
 
MySQL 强制锁名的最大长度为 64 个字符。
 
GET_LOCK() 可用于实现应用程序锁或模拟记录锁。名称会在服务器范围内被锁定。如果一个名称在一个会话中被锁定,GET_LOCK() 将阻塞另一个会话对同名锁的任何请求。这使得遵从给定锁名的客户端可以使用该名称执行协作咨询锁。但是请注意,它还允许不在合作客户端集合中的客户端锁定某个名称(无意或有意),从而阻止任何合作客户端锁定该名称。降低这种可能性的一种方法是使用特定于数据库或特定于应用程序的锁名。例如,使用锁名如 db_name.str  app_name.str
 
如果多个客户端正在等待一个锁,那么它们获取锁的顺序是未定义的。应用程序不应该假设客户端获取锁的顺序与发出锁请求的顺序相同。
 
GET_LOCK() 对于基于语句的复制是不安全的。如果 binlog_format 设置为 STATEMENT 时使用此函数,则会记录一个警告。
 
注意
 
通过获取多个命名锁的功能,单个语句可以获取大量锁。例如:
 
INSERT INTO ... SELECT GET_LOCK(t1.col_name) FROM t1;
 
这些类型的语句可能会产生某些负面影响。例如,如果语句部分失败并回滚,在失败点之前获得的锁仍然存在。如果本意是为了在插入的行和获取的锁之间存在对应,那么这个意图是不满足的。此外,如果按照一定的顺序授予锁是很重要的,请注意结果集的顺序可能会因优化器选择的执行计划而不同。由于这些原因,最好将应用程序限制为每条语句只执行一次锁获取调用。
 
● IS_FREE_LOCK(str)
 
检查名为 str 的锁是否可以自由使用(即未锁定)。如果锁是空闲的(没有被使用),则返回 1,如果锁正在使用,则返回 0,如果发生错误(例如错误参数),则返回 NULL
 
这个函数对于基于语句的复制是不安全的。如果 binlog_format 设置为 STATEMENT 时使用此函数,则会记录一个警告。
 
● IS_USED_LOCK(str)
 
检查名为 str 的锁是否正在使用(即锁定)。如果是,它返回持有锁的客户端会话的连接标识符。否则返回 NULL
 
这个函数对于基于语句的复制是不安全的。如果在 binlog_format 设置为 STATEMENT 时使用此函数,则会记录一个警告。
 
● RELEASE_ALL_LOCKS()
 
释放当前会话持有的所有命名锁,并返回释放的锁的数量(如果没有释放的锁,则返回0)
 
这个函数对于基于语句的复制是不安全的。如果在 binlog_format 设置为 STATEMENT 时使用此函数,则会记录一个警告。
 
● RELEASE_LOCK(str)
 
释放用 GET_LOCK() 获得的字符串 str 命名的锁。如果锁被释放,则返回 1,如果锁不是由这个线程建立的(在这种情况下锁没有被释放),则返回 0,如果命名锁不存在,则返回 NULL。如果锁不是通过调用 GET_LOCK() 获得,或者它之前已经被释放,那么锁就不存在。
 
DO 语句可以方便地与 RELEASE_LOCK() 一起使用。
 
这个函数对于基于语句的复制是不安全的。如果在 binlog_format 设置为 STATEMENT 时使用此函数,则会记录一个警告。
 

官方文档:
https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html
文章转载自林员外聊编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论