• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 锁定函数

    本节介绍用于操纵用户级锁的功能。

    锁定函数

    名称描述
    GET_LOCK()获取命名锁
    IS_FREE_LOCK()命名锁是否免费
    IS_USED_LOCK()是否使用了命名锁;如果为true,则返回连接标识符
    RELEASE_ALL_LOCKS()释放所有当前的命名锁
    RELEASE_LOCK()释放命名的锁

    • GET_LOCK(str,timeout)

      尝试str使用timeout秒数超时来获取具有字符串给定名称的锁。负值timeout表示无限超时。锁是排他的。当一个会话举行时,其他会话无法获得相同名称的锁。

      返回1是否成功获得了锁定,0尝试超时(例如,由于另一个客户端先前已锁定该名称)或NULL是否发生了错误(例如内存不足或线程被mysqladmin kill杀死)。

      当会话终止时(正常或异常),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()出现在“性能模式”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()对于基于语句的复制不安全。设置为时,如果使用此功能,binlog_format将记录警告STATEMENT

      警告

      具有获取多个命名锁的能力,单个语句就有可能获取大量锁。例如:

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

      这些类型的声明可能会产生某些不利影响。例如,如果该语句在执行过程中部分失败并回滚,则直到失败点为止获取的锁仍将存在。如果意图是在插入的行和获取的锁之间存在对应关系,则将无法满足该意图。同样,如果以一定顺序授予锁很重要,请注意结果集顺序可能会有所不同,具体取决于优化器选择的执行计划。由于这些原因,最好将应用程序限制为每个语句只能进行一次锁定获取调用。

      可以使用其他锁定接口作为插件服务或一组用户定义的函数。该接口提供锁名称空间和不同的读取和写入锁,这与由GET_LOCK()及相关函数提供的接口不同。有关详细信息,请参见“锁定服务”。

    • 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)

      释放由str所获得的字符串命名的锁GET_LOCK()。返回1该锁是否已释放,0该线程未建立锁(在这种情况下未释放锁)以及NULL指定的锁不存在。如果从未通过调用获得该锁,GET_LOCK()或者以前已释放过该锁,则该锁不存在。

      DO语句可以方便地与一起使用RELEASE_LOCK()。请参见“ DO语句”。

      此功能对于基于语句的复制不安全。设置为时,如果使用此功能,binlog_format将记录警告STATEMENT