MySQL 函数和运算符:锁函数

来自Wikioe
跳到导航 跳到搜索


锁函数:

Name Description
GET_LOCK() 获取命名锁

“GET_LOCK(str,timeout)”:尝试使用 timeout 秒的超时时间来获得具有由字符串 str 给出的名称的锁。timeout 为负值表示无限超时。锁是排他的。当一个会话举行时,其他会话无法获得相同名称的锁:

如果成功获得了锁定,则返回1;如果尝试超时(例如,因为另一个 Client 端先前已锁定该名称),则返回0;如果发生错误(例如内存不足或线程被mysqladmin kill杀死),则返回NULL
  • 通过“RELEASE_LOCK(str)”显式地释放通过“GET_LOCK(str,timeout)”获得的锁,或者在会话终止(正常或异常)时隐式释放。
  • 提交或回滚事务时,不会释放通过“GET_LOCK(str,timeout)”获得的锁。
  • 此功能对于基于语句的复制不安全。如果在 binlog_format 设置为 STATEMENT 时使用此功能,则会记录一条警告。


在 MySQL 5.7 中,使用元数据锁定(MDL)子系统重新实现了“GET_LOCK(str,timeout)”,并扩展了其功能。可以同时获取多个锁,并且“GET_LOCK(str,timeout)”不会释放任何现有锁。

  • 给定的会话甚至有可能获得相同名称的多个锁。其他会话无法获取具有该名称的锁,直到获取会话释放该名称的所有锁。

重新实现 MDL 的结果是,使用GET_LOCK()获得的唯一命名的锁出现在“Performance Schema metadata_locks”表中: “OBJECT_TYPE”列表示“USER LEVEL LOCK”,而“OBJECT_NAME”列表示锁名称。 在为相同名称获取多个锁的情况下,仅该名称的第一个锁在“metadata_locks”表中注册一行。该名称的后续锁会在该锁中增加一个计数器,但不会获取其他元数据锁。释放名称上的最后一个锁实例后,将删除该锁的“metadata_locks”行。

  • 获取多个锁的能力意味着 Client 端之间可能会出现死锁。发生这种情况时,服务器选择一个呼叫者,并以“ER_USER_LOCK_DEADLOCK”错误终止其锁定获取请求。此错误不会导致事务回滚。


在 MySQL 5.7 之前,只能获取一个同时锁定,并且“RELEASE_ALL_LOCKS()”释放任何现有的锁定。通过以下示例可以看出,自 MySQL 5.7 起,锁获取行为有所不同。假设您执行以下语句:

SELECT GET_LOCK('lock1',10);
SELECT GET_LOCK('lock2',10);
SELECT RELEASE_LOCK('lock2');
SELECT RELEASE_LOCK('lock1');
  1. 在 MySQL 5.7 或更高版本中,第二个“GET_LOCK()”获得第二个锁,并且两个“RELEASE_LOCK()”调用均返回 1(成功)。
  2. 在 MySQL 5.7 之前,第一个“RELEASE_LOCK()”释放第一个锁('lock1'),第二个“RELEASE_LOCK()”返回NULL(失败),因为没有'lock1'要释放。


  • 如果多个 Client 端正在 await 锁,则它们获取锁的顺序是不确定的。应用程序不应假定 Client 端将按照发出锁定请求的顺序来获得锁定。
IS_FREE_LOCK() 命名锁是否空闲

“IS_FREE_LOCK(str)”:检查名为 str 的锁是否空闲可用(即未锁定)。如果锁是空闲的(没有人正在使用锁),则返回1;如果正在使用锁,则返回0;如果发生错误(例如不正确的参数),则返回NULL

  • 此功能对于基于语句的复制不安全。如果在 binlog_format 设置为 STATEMENT 时使用此功能,则会记录一条警告。
IS_USED_LOCK() 是否使用了命名锁;如果为 true,则返回连接标识符

“IS_USED_LOCK(str)”:检查名为 str 的锁是否正在使用(即已锁定)。如果是这样,它将返回持有该锁的 Client 端会话的连接标识符。否则,它返回NULL。

  • 此功能对于基于语句的复制不安全。如果在 binlog_format 设置为 STATEMENT 时使用此功能,则会记录一条警告。
RELEASE_ALL_LOCKS() 释放所有当前命名的锁

“RELEASE_ALL_LOCKS()”:释放当前会话持有的所有命名锁,并返回释放的锁数(如果没有锁,则返回 0)

  • 此功能对于基于语句的复制不安全。如果在 binlog_format 设置为 STATEMENT 时使用此功能,则会记录一条警告。
RELEASE_LOCK() 释放命名的锁

“RELEASE_LOCK(str)”:释放由“GET_LOCK()”获得的字符串 str 命名的锁。如果释放了锁,则返回1;如果不是由该线程构建的锁(在这种情况下不释放锁),则返回0;如果命名的锁不存在,则返回NULL

  • 如果从未通过调用“GET_LOCK()”获得该锁,或者该锁先前已被释放,则该锁不存在。
  • DO语句 与 RELEASE_LOCK() 结合使用非常方便。【???】
  • 此功能对于基于语句的复制不安全。如果在 binlog_format 设置为 STATEMENT 时使用此功能,则会记录一条警告。