28.3.1 锁定服务

MySQL 发行版提供了一个锁定界面,该界面有两个级别可用:

  • 作为 C 语言接口,可以从服务器插件或用户定义函数作为插件服务调用

  • 在 SQL 级别,作为一组用户定义的函数,这些函数 Map 到对服务例程的调用

有关插件服务的一般信息,请参见第 28.3 节“用于插件的 MySQL 服务”。有关用户定义函数的一般信息,请参见第 28.4.2 节“添加用户定义的功能”

锁定接口具有以下 Feature:

  • 锁具有三个属性:锁命名空间,锁名称和锁模式:

  • 锁由名称空间和锁名称的组合来标识。命名空间使不同的应用程序可以使用相同的锁名,而不会在单独的命名空间中创建锁而导致冲突。例如,如果应用程序 A 和 B 分别使用ns1ns2的名称空间,则每个应用程序可以使用锁名lock1lock2,而不会干扰其他应用程序。

    • 锁定模式为读或写。共享读取锁:如果某个会话在给定的锁标识符上具有读取锁,则其他会话可以在同一标识符上获取读锁。写锁是互斥的:如果一个会话在给定的锁标识符上具有写锁,则其他会话无法在同一标识符上获取读或写锁。
  • 命名空间和锁名称必须为非NULL,非空且最大长度为 64 个字符。指定为NULL的名称空间或锁名称,空字符串或长于 64 个字符的字符串会导致ER_LOCKING_SERVICE_WRONG_NAME错误。

  • 锁定接口将名称空间和锁定名称视为二进制字符串,因此比较区分大小写。

  • 锁定接口提供获取锁定和释放锁定的功能。调用这些功能不需要特殊特权。特权检查是调用应用程序的责任。

  • 如果没有立即可用,可以 await 锁。锁获取调用采用整数超时值,该值指示放弃之前要 await 多少秒才能获取锁。如果没有成功获取锁而达到超时,则会发生ER_LOCKING_SERVICE_TIMEOUT错误。如果超时为 0,则没有 await,如果无法立即获取锁,则调用将产生错误。

  • 锁定接口检测不同会话中的锁定获取调用之间的死锁。在这种情况下,锁定服务选择一个呼叫者,并以ER_LOCKING_SERVICE_DEADLOCK错误终止其锁定获取请求。此错误不会导致事务回滚。要选择发生死锁的会话,锁定服务将优先选择持有读锁定的会话而不是持有写锁定的会话。

  • 一个会话可以通过单个锁获取调用获取多个锁。对于给定的呼叫,锁获取是原子的:如果获取了所有锁,则该呼叫成功。如果获取任何锁均失败,则该调用将不获取锁并失败,通常会出现ER_LOCKING_SERVICE_TIMEOUTER_LOCKING_SERVICE_DEADLOCK错误。

  • 会话可以为同一锁标识符(名称空间和锁名称组合)获取多个锁。这些锁实例可以是读锁,写锁或两者的混合。

  • 会话中获取的锁通过调用释放锁函数显式释放,或者在会话终止时(正常或异常)隐式释放。事务提交或回滚时不会释放锁。

  • 在会话中,给定名称空间的所有锁在释放时都会一起释放。

锁定服务提供的接口不同于GET_LOCK()和相关的 SQL 函数(请参见第 12.14 节“锁定功能”)提供的接口。例如,GET_LOCK()不实现名称空间,仅提供排他锁,不提供不同的读写锁。