# 12.15 锁定功能

本节介绍用于操作用户级锁的函数。

表 12.19 锁定功能

姓名 描述
GET_LOCK() 获取命名锁
IS_FREE_LOCK() 命名锁是否空闲
IS_USED_LOCK() 命名锁是否在使用中;如果为真,则返回连接标识符
RELEASE_ALL_LOCKS() 释放所有当前的命名锁
RELEASE_LOCK() 释放命名锁
  • GET_LOCK(*字符串*,*暂停*)

    尝试使用字符串给出的名称获取锁*字符串,使用超时暂停秒。一个负面的暂停*value 表示无限超时。锁是独占的。当一个会话持有时,其他会话不能获得同名的锁。

    退货1如果成功获得锁,0如果尝试超时(例如,因为另一个客户端先前已锁定该名称),或者空值如果发生错误(例如内存不足或线程被杀死)mysqladmin 杀)。

    获得的锁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()出现在性能架构中元数据锁桌子。这OBJECT_TYPE专栏说用户等级锁定OBJECT_NAME列表示锁名称。在获取多个锁的情况下相同的name,只有 name 的第一个锁在元数据锁桌子。名称的后续锁会增加锁中的计数器,但不会获取额外的元数据锁。这元数据锁当名称上的最后一个锁实例被释放时,锁的行被删除。

    获取多个锁的能力意味着客户端之间存在死锁的可能性。当这种情况发生时,服务器会选择一个调用者并终止它的锁获取请求。ER_USER_LOCK_DEADLOCK (opens new window)错误。此错误不会导致事务回滚。

    MySQL 强制锁定名称的最大长度为 64 个字符。

    GET_LOCK()可用于实现应用程序锁或模拟记录锁。名称在服务器范围内被锁定。如果一个名字在一个会话中被锁定,GET_LOCK()阻止另一个会话对同名锁的任何请求。这使同意给定锁名称的客户端能够使用该名称来执行协作咨询锁定。但请注意,它还会使不在合作客户端集合中的客户端无意或故意锁定名称,从而防止任何合作客户端锁定该名称。降低这种可能性的一种方法是使用特定于数据库或特定于应用程序的锁名称。例如,使用形式的锁名称*db_name.str要么app_name.str*.

    如果多个客户端正在等待一个锁,它们获取锁的顺序是不确定的。应用程序不应假定客户端获取锁的顺序与它们发出锁请求的顺序相同。

    GET_LOCK()对于基于语句的复制是不安全的。如果您在以下情况下使用此功能,则会记录警告binlog_format被设定为陈述.

    自从GET_LOCK()仅在单个上建立锁定mysqld,它不适合与 NDB Cluster 一起使用,它无法跨多个 MySQL 服务器强制执行 SQL 锁。看第 23.2.7.10 节,“与多个 NDB 集群节点相关的限制”, 了解更多信息。

    警告

    有了获取多个命名锁的能力,一条语句就可以获取大量的锁。例如:

    INSERT INTO ... SELECT GET_LOCK(t1.col_name) FROM t1;
    

    这些类型的陈述可能会产生某些不利影响。例如,如果语句中途失败并回滚,则在失败点之前获取的锁仍然存在。如果意图是在插入的行和获取的锁之间存在对应关系,则不满足该意图。此外,如果按特定顺序授予锁很重要,请注意结果集顺序可能因优化器选择的执行计划而异。由于这些原因,最好将应用程序限制为每个语句的单个锁获取调用。

    不同的锁定接口可用作插件服务或一组可加载功能。这个接口提供了锁命名空间和不同的读写锁,不像提供的接口GET_LOCK()及相关功能。有关详细信息,请参阅第 5.6.9.1 节,“锁定服务”.

  • IS_FREE_LOCK(*字符串*)

    检查锁是否命名*字符串*可以免费使用(即未锁定)。退货1如果锁是空闲的(没有人使用锁),0如果锁正在使用中,并且空值如果发生错误(例如不正确的参数)。

    此函数对于基于语句的复制是不安全的。如果您在以下情况下使用此功能,则会记录警告binlog_format被设定为陈述.

  • IS_USED_LOCK(*字符串*)

    检查锁是否命名*字符串*正在使用中(即锁定)。如果是,则返回持有锁的客户端会话的连接标识符。否则,它返回空值.

    此函数对于基于语句的复制是不安全的。如果您在以下情况下使用此功能,则会记录警告binlog_format被设定为陈述.

  • RELEASE_ALL_LOCKS()

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

    此函数对于基于语句的复制是不安全的。如果您在以下情况下使用此功能,则会记录警告binlog_format被设定为陈述.

  • 释放_锁(*字符串*)

    释放由字符串命名的锁*字符串*那是用GET_LOCK().退货1如果锁被释放,0如果该线程没有建立锁(在这种情况下,锁没有被释放),并且空值如果命名锁不存在。如果从未通过调用获得该锁,则该锁不存在GET_LOCK()或者如果它之前已发布。

    语句使用起来很方便RELEASE_LOCK().看第 13.2.3 节,“DO 声明”.

    此函数对于基于语句的复制是不安全的。如果您在以下情况下使用此功能,则会记录警告binlog_format被设定为陈述.