美文网首页
第四章 锁定和并发控制(四)

第四章 锁定和并发控制(四)

作者: Cache技术分享 | 来源:发表于2022-06-20 09:07 被阅读0次

第四章 锁定和并发控制(四)

避免死锁

增量锁定具有潜在危险,因为它可能导致称为死锁的情况。当两个进程各自对已被另一个进程锁定的变量断言增量锁定时,就会出现这种情况。因为尝试的锁是增量的,所以现有的锁不会被释放。结果,每个进程在等待另一个进程释放现有锁的同时挂起。

举个例子:

  1. 进程 A 发出此命令:lock + ^MyGlobal(15)
  2. 进程 B 发出此命令:lock + ^MyOtherGlobal(15)
  3. 进程 A 发出此命令:lock + ^MyOtherGlobal(15)

LOCK 命令不返回;进程被阻塞,直到进程 B 释放这个锁。

  1. 进程 B 发出此命令:lock + ^MyGlobal(15)

LOCK 命令不返回;进程被阻塞,直到进程 A 释放这个锁。但是,进程 A 被阻塞,无法释放锁。现在这些进程都在等待对方。

有几种方法可以防止死锁:

  • 始终包含 timeout 参数。
  • 对于发出增量 LOCK 命令的顺序,请遵循严格的协议。只要所有进程都遵循相同的锁名称顺序,就不会发生死锁。一个简单的协议是按排序顺序添加锁。
  • 使用简单锁定而不是增量锁定;也就是说,不要使用 + 运算符。如前所述,对于简单锁定,LOCK 命令首先释放进程持有的所有先前锁定。 (然而,在实践中,简单的锁定并不经常使用。)

如果发生死锁,可以使用管理门户或 ^LOCKTAB

锁的实际用途

本节介绍在实践中使用锁的基本方法。

控制对应用程序数据的访问

锁经常用于控制对存储在全局变量中的应用程序数据的访问。应用程序可能需要读取或修改此数据的特定部分,并且应用程序将在执行此操作之前创建一个或多个锁,如下所示:

  • 如果应用程序需要读取一个或多个全局节点,并且不希望其他进程在读取操作期间修改这些值,请为这些节点创建共享锁。
  • 如果应用程序需要修改一个或多个全局节点,并且不希望其他进程在修改期间读取这些节点,请为这些节点创建排他锁。

然后按计划阅读或进行修改。完成后,取下锁。

请记住,锁定机制纯粹按照约定工作。任何其他将读取或修改这些节点的代码也必须在执行这些操作之前尝试获取锁。

防止同步行为

锁也用于防止多个进程执行相同的活动行为。在这种情况下,还使用了GLOBAL,但GLOBAL包含用于应用程序内部目的的数据,而不是纯应用程序数据。作为一个简单的示例,假设有一个例程 (^NightlyBatch),在任何给定时间都不应由多个进程运行。该例程可以在其处理的早期阶段执行以下操作:

  1. 在特定全局节点上创建排他锁,例如 ^AppStateData("NightlyBatch")。为此操作指定超时。
  2. 如果获得锁,则在全局中设置节点以记录例程已启动(以及任何其他相关信息)。例如:
 set ^AppStateData("NightlyBatch")=1
 set ^AppStateData("NightlyBatch","user")=$USERNAME

或者,如果在超时期限内未获得锁,则退出并显示错误消息,指示该例程已启动。

然后,在其处理结束时,同一例程将清除适用的全局节点并释放锁。

以下部分示例演示了这种技术,该技术改编自内部使用的代码:

/// w ##class(PHA.TEST.AdvancedConcepts).Lock()
ClassMethod Lock()
{
    lock ^AppStateData("NightlyBatch"):0
    if '$TEST {
        write "现在无法运行此例程."
        write !, "此例程当前由用户运行: "_^AppStateData("NightlyBatch","user")
        quit
    }
    set ^AppStateData("NightlyBatch") = 1
    set ^AppStateData("NightlyBatch","user") = $USERNAME
    set ^AppStateData("NightlyBatch","starttime") = $h
    b
    kill ^AppStateData("NightlyBatch")
    lock -^AppStateData("NightlyBatch")
}

image.png

相关文章

  • 第四章 锁定和并发控制(四)

    第四章 锁定和并发控制(四) 避免死锁 增量锁定具有潜在危险,因为它可能导致称为死锁的情况。当两个进程各自对已被另...

  • AtomicInteger的实现原理

    AtomicInteger:使用非阻塞算法(无锁定无等待)实现并发控制,相比synchronized和Lock(阻...

  • InnoDB加锁分析

    InnoDB加锁分析 在事务的并发控制,MySQL使用MVCC来支持快照读和使用加锁来支持锁定读两种方式,锁定通过...

  • SQL语句总结----并发控制(持续更新)

    SQL使用资源锁定的方式管理用户的并发操作: 乐观并发控制:假定用户之间不太可能发生资源冲突,允许用户在不锁定任何...

  • 第一章 锁定和并发控制制(一)

    [toc] 第一章 锁定和并发控制(一) 任何多进程系统的一个重要特征是并发控制,即防止不同进程同时更改特定数据元...

  • 第三章 锁定和并发控制(三)

    第三章 锁定和并发控制(三) 升级锁 使用升级锁来管理大量锁。当锁定数组的节点时,它们是相关的,特别是当将多个节点...

  • 乐观锁和悲观锁

    一、悲观锁在修改数据之前先锁定,再修改的方式被称之为悲观并发控制。这是一种对数据的修改持有悲观态度的并发控制方式。...

  • 第二章 锁定和并发控制(二)

    第二章 锁定和并发控制(二) 关于零超时的说明 如上所述,如果您将 timeout 指定为 0, 会添加锁。但是,...

  • 乐观锁与悲观锁

    乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段 悲观并发控制(悲观锁) 它可以阻止一个...

  • 数据库并发控制——悲观锁、乐观锁、MVCC

    三种并发控制:悲观并发控制、乐观并发控制、多版本并发控制。 悲观并发控制(又名“悲观锁”,Pessimistic ...

网友评论

      本文标题:第四章 锁定和并发控制(四)

      本文链接:https://www.haomeiwen.com/subject/vkndvrtx.html