#Caché

0 关注者 · 975 帖子

  

InterSystems Caché 是一个多模型 DBMS 和应用服务器。

查看此处提供的更多详细信息

文档

文章 姚 鑫 · 七月 5, 2022 5m read

第十九章 使用工作队列管理器(二)

基本工作流程

可以通过执行以下步骤来使用工作队列管理器:

  1. ObjectScript 代码划分为工作单元,这些工作单元是满足特定要求的类方法或子例程。
  2. 创建一个工作队列,它是 %SYSTEM.WorkMgr 类的一个实例。为此,请调用 %SYSTEM.WorkMgr 类的 %New() 方法。该方法返回一个工作队列。

可以指定要使用的并行worker jobs的数量,也可以使用默认值,这取决于机器和操作系统。此外,如果已创建类别,则可以指定应从中获取job的类别。

创建工作队列时,工作队列管理器会创建以下工件:

  • 包含有关工作队列的信息的全局变量,例如工作队列在哪个命名空间中运行
  • 工作队列必须处理的序列化工作单元的位置和事件队列
  • 在工作队列完成处理工作单元时创建的完成事件的位置和事件队列
  1. 将工作单元(也称为工作项)添加到工作队列。为此,可以调用 Queue()QueueCallback() 方法。作为参数,传递类方法(或子例程)的名称和任何相应的参数。

对添加到队列的项目立即开始处理。

如果队列中的项目多于队列可用的worker jobs,则job会竞争清空队列。例如,如果有 100 个项目和四个job,则每个job从队列的头部移除一个项目,处理它,然后返回到队列的头部以移除并处理另一个项目。这种模式一直持续到队列为空。

0
0 91
文章 姚 鑫 · 七月 4, 2022 7m read

第十八章 使用工作队列管理器(一)

工作队列管理器是的一项功能,使能够通过以编程方式将工作分配给多个并发进程来提高性能。在引入工作队列管理器之前,可能已经使用 JOB 命令在应用程序中启动多个进程并使用自定义代码管理这些进程(以及任何导致的故障)。工作队列管理器提供了一个高效且直接的 API,使能够卸载流程管理。

代码在多个地方内部使用工作队列管理器。可以将它用于自己的需求,如以下部分中的高级描述。

背景

计算机硬件开发的最新创新趋向于高性能、多处理器或多核架构。与此同时,内存和网络设备的速度也只是慢慢地提高了。 开发了工作队列管理器以响应这些趋势并根据以下原则:

  • 硬件资源,包括 CPU 和 I/O、内存和网络设备,都是固定的。
  • 必须尽可能高效地使用硬件资源,以最大限度地提高其执行业务任务的速度。
  • 为了实现最大效率,工作队列管理器必须改善在执行ObjectScript 代码时可能出现的 CPU 利用率不足的问题。
  • 解决 CPU 利用率不足的方法包括排队和优先级划分。

尽管整个数据平台旨在尽可能高效地利用系统中的硬件资源,但该平台的工作队列管理器功能专门设计用于利用现代硬件配置中可用的额外 CPU 资源。工作队列管理器有两个关键用途:

0
0 100
文章 Jingwei Wang · 七月 4, 2022 11m read

高可用性(HA)指的是使系统或应用程序在很高比例的时间内保持运行,最大限度地减少计划内和计划外的停机时间。

维持系统高可用性的主要机制被称为故障转移。在这种方法下,一个故障的主系统被一个备份系统所取代;也就是说,生产系统故障转移到备份系统上。许多HA配置还提供了灾难恢复(DR)的机制,即在HA机制无法保持系统的可用性时,也能及时恢复系统的可用性。

本文简要讨论了可用于基于InterSystems IRIS的应用程序的HA策略机制,提供了HA解决方案的功能比较,并讨论了使用分布式缓存的故障转移策略。

操作系统级别的集群HA

在操作系统层面上提供的一个常见的HA解决方案是故障转移集群,其中主要的生产系统由一个(通常是相同的)备用系统补充,共享存储和一个跟随活动成员的集群IP地址。在生产系统发生故障的情况下,备用系统承担生产工作量,接管以前在故障主系统上运行的程序和服务。备用机必须能够处理正常的生产工作负载,只要恢复故障主机所需的时间就可以了。也可以选择让备用机成为主机,一旦主机恢复,故障主机将成为备用机。

0
0 171
文章 姚 鑫 · 七月 3, 2022 5m read

第十七章 进程内存

介绍

进程使用许多不同的资源来实现其目标。其中包括部分或全部 CPU 周期、内存、外部存储、网络带宽等。这篇文章是关于内存使用的。具体来说,它处理为数据存储分配的内存,例如:

  • 公共和私有变量

当第一次为它们分配值时,它们被分配了内存空间。在局部数组的情况下,局部变量名称加上所有下标的值的组合引用单个变量值。

除了包含极长字符串的变量外,变量会占用与 $STORAGE 相关的空间。包含极长字符串的变量以不同方式存储,并且不占用 $STORAGE 中的空间。

  • 对象实例

每当实例化一个对象时,都会分配空间来保存对象的当前内容以及它所引用的对象。删除最后一个对象引用时返回该空间。

  • 本地 I/O 缓冲区

将与该进程正在使用的设备相关联的 I/O 缓冲区存储在进程空间中。

管理进程空间

进程从用于上述实体的初始内存池开始。当应用程序创建它们时,它们会消耗池中的内存;当应用程序删除它们时,它们的内存将返回到池中。例如,当一个例程开始执行时,总是会创建消耗一些内存的局部变量;当例程返回并且这些变量超出范围时,这些变量使用的内存将被返回并可供重用。

0
0 111
文章 姚 鑫 · 七月 2, 2022 5m read

第十六章 字符串本地化和消息字典(二)

XML 消息文件

XML 消息文件是消息字典的导出。这也是希望导入的任何消息的必需格式。

只要有可能,XML 消息文件应该使用 UTF-8 编码。但是,在某些情况下,开发人员或翻译人员可能会使用本地平台编码,例如 shift-jis,以便于编辑 XML 消息文件。无论 XML 文件使用何种编码,应用程序的语言环境都必须支持它,并且它必须能够表达该语言的消息。

XML 消息文件可能包含一种语言和多个域的消息。

<MsgFile> Element

<MsgFile> 元素是 XML 消息文件的顶级容器,每个文件只有一个 <MsgFile>元素。

<MsgFile>元素有一个必需的属性,Language<MsgFile>Language 属性的值是一个全小写的 RFC1766 代码,用于标识文件的语言。它由一个或多个部分组成:主要语言标签(例如 enja)可选地后跟连字符 (-) 和次要语言标签(en-gbja-jp)。

在以下示例中,此语言为“en”(英语)。

0
0 81
文章 姚 鑫 · 七月 1, 2022 4m read

第十五章 字符串本地化和消息字典(一)

本文概述了字符串本地化,并描述了如何导出、导入和管理消息字典。

字符串本地化

当本地化应用程序的文本时,会创建一种语言的文本字符串清单,然后当应用程序区域设置不同时,建立约定以另一种语言替换这些消息的翻译版本。

支持以下本地化字符串的过程:

  1. 开发人员在他们的代码中包含可本地化的字符串(在REST 应用程序或商业智能模型中)。

这种机制各不相同,但最常见的机制是 $$$Text 宏。代替硬编码的文字字符串,开发人员包含 $$$Text 宏的实例,为宏参数提供如下值:

  • 默认字符串
  • 此字符串所属的域(将字符串分组为域时,本地化更易于管理)
  • 默认字符串的语言代码
write "Hello world"

替换为

write $$$TEXT("Hello world","sampledomain","en-us")
  1. 编译代码时,编译器会在消息字典中为 $$$Text 宏的每个唯一实例生成条目。

消息字典是全局的,因此可以在管理门户中轻松查看(例如)。有一些类方法可以帮助完成常见任务。

  1. 开发完成后,发布工程师导出该域或所有域的消息字典。

结果是一个或多个 XML 消息文件,其中包含原始语言的文本字符串。

0
0 127
文章 姚 鑫 · 六月 30, 2022 2m read

第十四章 信号(四)- 多进程任务示例

可根据此思想进行多任务启动查询汇总数据。

原理

  • 利用job机制开启后台进程。
  • 利用loop循环减少进程的数量等于开启进程的数量,判断多进程任务是否完成。
  1. 创建表并插入1000W条数据,统计Moeny字段总金额

  2. 创建demo代码如下。

0
0 87
文章 姚 鑫 · 六月 29, 2022 10m read

第十三章 信号(三)- 示例演示

运行示例

MainProducerConsumer 这三个类中的每一个都有自己的 Run 方法,最好在各自的终端窗口中运行它们。每次运行时,它都会显示它为日志生成的消息。一旦用户通过提供它正在等待的输入来响应 Main 类,MainRun 方法将终止删除信号量。然后,用户可以通过键入命令查看所有进程的合并日志文件的显示

  Do ##class(Semaphore.Util).ShowLog()

注意:以下所有示例都假定所有类都已在“USER”命名空间中编译。

示例 1 - 创建和删除信号量

最简单的例子演示了信号量的创建和销毁。它使用 Semaphore.Main 类。请执行下列操作:

  1. 打开一个终端窗口。
  2. 输入命令——
Do ##class(Semaphore.Main).Run()
  1. 该方法创建信号量。如果成功,将看到消息“输入任何字符以终止运行方法”。按下 Enter 键。该方法显示信号量的初始化值,将其删除,然后退出。
  2. 通过发出命令显示日志文件
Do ##class(Semaphore.Util).ShowLog()

按照上述步骤在终端窗口中显示的消息示例如下

0
0 90
文章 姚 鑫 · 六月 27, 2022 7m read

第十二章 信号(二)- 生产者消费者示例

下面是一系列使用信号量实现生产者/消费者场景的类。 “主”进程初始化信号量并等待用户指示活动已全部完成。生产者在循环中随机增加一个信号量值,更新之间的延迟可变。消费者尝试在随机时间从信号量中删除随机数量,也是在循环中。该示例由 5 个类组成:

  • Main – 初始化环境并等待信号量上的活动完成的类。
  • Counter – 实现信号量本身的类。它记录它的创建以及由于信号量在等待列表中而发生的任何回调。
  • Producer – 一个类,其主要方法增加信号量值。增量是一个随机选择的小整数。完成增量后,该方法会在下一个增量之前延迟一小段随机数秒。
  • Consumer 消费者——这是对生产者的补充。此类的主要方法尝试将信号量减少一个随机选择的小整数。它将递减请求添加到其等待列表中,等待时间也是随机选择的秒数。
  • Util - 这个类有几个方法被示例的其他类使用。几种方法解决了为所有活动维护公共日志的问题;其他人解决了多个消费者和多个生产者的命名问题。

注意:组成这些类的代码特意写得简单。尽可能地,每个语句只完成一个动作。这应该使用户更容易和更直接地修改示例。

Class: Semaphore.Main

此类建立演示环境。它调用实用程序类来初始化日志和名称索引工具。然后它用初始值 0 初始化公共信号量,并等待用户输入一个字符(通常是 ENTER 键),表明实验已经完成。

0
0 90
文章 Weiwei Gu · 六月 27, 2022 6m read

Globals,这些存储数据的魔剑,已经存在了一段时间,但是没有多少人能够有效地使用它们,也没有多少人知道这个超级武器。

如果你把Globals的东西用在它们真正能发挥作用的地方,其结果可能是惊人的,要么是性能的提高,要么是整体解决方案的大幅简化 (1, 2).

Globals提供了一种特殊的存储和处理数据的方式,它与SQL表完全不同。它们在1966年首次出现在 M(UMPS)编程语言中, 该语言最初用于医学数据库。现在它仍然以同样的方式被使用,但也被其他一些以可靠性和高性能为首要任务的行业所采用:金融、交易等。

后来M(UMPS)演变为 Caché ObjectScript (COS). COS是由InterSystems公司开发的,作为M的一个超集. 其原始语言仍然被开发者社区所接受,并在一些实现中保持活力。在网络上有几个活跃的网址,比如:MUMPS Google group, Mumps User's group), effective ISO Standard等等

现代基于Globals的数据库支持交易、日志、复制、分区等。这意味着它们可以被用来构建现代的、可靠的、快速的分布式系统。

1
0 281
文章 姚 鑫 · 六月 26, 2022 7m read

第十一章 信号(一) - 概念

背景

维基百科对信号量有这样的定义:“在计算机科学中,特别是在操作系统中,信号量是一种变量或抽象数据类型,用于控制多个进程在并行编程或多用户环境中对公共资源的访问。”信号量不同于互斥体(或锁)。互斥锁最常用于管理竞争进程对单个资源的访问。当一个资源有多个相同的副本并且这些副本中的每一个都可以由单独的进程同时使用时,就会使用信号量。

考虑一个办公用品商店。它可能有几台复印机供其客户使用,但每台复印机一次只能由一个客户使用。为了控制这一点,有一组键可以启用机器并记录使用情况。当客户想要复印文件时,他们向职员索取钥匙,使用机器,然后归还钥匙,并支付使用费。如果所有机器都在使用,客户必须等到钥匙归还。保存键的位置用作信号量。

该示例可以进一步推广到包括不同类型的复印机,也许可以通过它们可以制作的副本的大小来区分。在这种情况下,将有多个信号量,如果复制者在复制的大小上有任何重叠,那么希望复制共同大小的客户将有两个资源可供提取。

介绍

信号量是共享对象,用于在进程之间提供快速、高效的通信。每个信号量都是类 %SYSTEM.Semaphore 的一个实例。信号量可以建模为一个共享变量,它包含一个 64 位非负整数。信号量上的操作在共享它的所有进程中以同步的方式更改变量的值。按照惯例,值的变化会在共享信号量的进程之间传递信息。

0
0 137
文章 Michael Lei · 六月 26, 2022 5m read

前一篇文章中,我已经演示了一种简单的方法来记录数据的变化。在这个时候,我改变了负责记录审计数据的 "审计抽象类 "和记录审计日志的数据结构。

我已经将数据结构改为父子结构,其中将有两个表来记录 "交易 "和在该交易中改变的 "字段的值"。

看一下新的数据模型:

看看从 "审计类 "改变的代码吧:

0
0 183
文章 姚 鑫 · 六月 25, 2022 2m read

第十章 设置结构化日志记录(二)

注:IRIS有,Cache无。

启用结构化日志记录

^LOGDMN 例程允许管理结构化日志记录;还有一个基于类的 API,将在下一节中介绍。

要使用 ^LOGDMN 启用结构化日志记录:

  1. 打开终端并输入以下命令:
set $namespace="%sys"
do ^LOGDMN

这将启动一个带有以下提示的例程:

 
1) Enable logging
2) Disable logging
3) Display configuration
4) Edit configuration
5) Set default configuration
6) Display logging status
7) Start logging
8) Stop logging
9) Restart logging
 
LOGDMN option?
  1. 4 以便可以指定配置详细信息。然后,该例程会提示输入以下项目:

a. 最低日志级别,以下之一:

  • -2 — 详细的调试消息(例如十六进制转储)。
  • -1 — 不太详细的调试消息。
  • 0 — 信息性消息,包括所有审计事件。
  • 1(默认值)— 警告,表示可能需要注意但未中断操作的问题。
  • 2 — 严重错误,表明问题已中断操作。
  • 3 — 致命错误,表示问题导致系统无法运行。

b. 管道命令,它指定系统将结构化日志发送到哪里。输入以下形式的响应:

0
0 92
文章 姚 鑫 · 六月 24, 2022 4m read

第九章 设置结构化日志记录(一)

IRIS 支持结构化日志记录。

创建多个日志,每个日志用于不同的目的。从以前的产品迁移过来的客户可以像过去一样利用这些日志,但现在还可以将所有日志信息导入一个单一的、中央的、机器可读的日志文件——结构化日志。然后可以将此文件与第三方分析工具一起使用。

本文概述了结构化日志中的信息,展示了日志示例,并描述了如何启用结构化日志记录。

结构化日志中可用的信息

当启用结构化日志记录时,系统会将相同的数据写入结构化日志,它也会写入其他日志(无论哪个)。例如,系统将相同的行写入messages.log 和结构化日志。

启用结构化日志记录后,结构化日志包含以下所有信息:

  • 写入messages.log 的信息。这包括需要注意的警报、有关系统启动和关闭的信息、有关日志文件和 WIJ 文件的高级信息、有关配置更改 (CPF) 的信息以及与许可相关的信息。
  • 写入审计数据库的信息。详细信息取决于正在审核的事件。

示例输出

本部分显示结构化日志记录实用程序的示例输出,用于名称/值对格式和 JSON 格式。

名称/值对

以下输出使用格式选项 NVP(名称/值对)。此示例经过编辑以用于显示目的;在实际输出中,每个条目只占一行,条目之间没有空行。

0
0 118
文章 姚 鑫 · 六月 23, 2022 3m read

第八章 操作位和位串(四)

操作以整数形式实现的位串

设置位

要创建一个存储为整数的新位串,请对每个位求和 2 的幂:

set bitint = (2**2) + (2**5) + (2**10)
 
write bitint
1060

要将现有位串中的位设置为 1,请使用 $zboolean 函数(逻辑 OR)的选项7(arg1 ! arg2)

set bitint = $zboolean(bitint, 2**4, 7)

write bitint
1076

要将现有位串中的位设置为 0,请使用 $zboolean 函数的选项 2(arg1 & ~arg2)


set bitint = $zboolean(bitint, 2**4, 2)

write bitint
1060

要在现有位串中切换位,请使用 $zboolean 函数(逻辑 XOR)的选项 6(arg1 ^ arg2)

set bitint = $zboolean(bitint, 2**4, 6)

write bitint
1076
set bitint = $zboolean(bitint, 2**4, 6)

write bitint
1060

测试位是否已设置

要将位字符串显示为整数,可以使用如下方法,该方法循环位并使用 $zboolean 函数:

0
0 108
文章 Lilian Huang · 六月 23, 2022 2m read

InterSystems许可证是指InterSystems发放的电子或纸质版的产品许可证,内容包括许可证订购日期、产品描述等。

激活码/License KeyInterSystems随许可证发放的许可软件激活码。通常情况下,客户收到的是电子许可证。

以下是一些许可证,激活码/License key常见咨询问题参考:

  1. 收到电子许可证后,如何获取纸质版许可证?

纸质版许可证或是安装介质盘,可通过合作伙伴或是致电原厂核验许可证信息后获取。

  1. 如需申请WRC支持,需要

申请准备:

  • WRC账号,如无请通过WRC联络信息申请WRC账号
  • 故障问题描述
  • 许可证或激活码/License key
  • 最终客户名称 

WRC全球响应中心联络信息:

  1. 如何查询您的授权文件客户名和授权密钥?

方法1: 使用管理门户

以管理员身份登录到系统管理门户,进入菜单:系统管理>软件许可颁发>软件许授权码 (或英文菜单:System Administartion>Licensing>License Key)

记录客户名和授权密钥:

方法2 :使用命令行

0
0 433
文章 姚 鑫 · 六月 22, 2022 4m read

第七章 操作位和位串(三)

操作位串

要创建新的位串,请使用 $bit 函数将所需位设置为 1

kill bitstring
 
set $bit(bitstring, 3) = 1
 
set $bit(bitstring, 6) = 1
 
set $bit(bitstring, 11) = 1

使用 $bit 将现有位串中的位设置为 1

set $bit(bitstring, 5) = 1

使用 $bit 将现有位串中的位设置为 0

set $bit(bitstring, 5) = 0

由于位串中的第一位是位 1,因此尝试设置位 0 会返回错误:

set $bit(bitstring, 0) = 1
 
SET $BIT(bitstring, 0) = 1
^
<VALUE OUT OF RANGE>

测试位是否已设置

要测试是否在现有位串中设置了位,还可以使用 $bit 函数:

write $bit(bitstring, 6)
1
write $bit(bitstring, 5)
0

如果测试未明确设置的位,则 $bit 返回 0:

write $bit(bitstring, 4)
0
write $bit(bitstring, 55)
0

显示位

要显示位串中的位,请使用 $bitcount 函数获取位串中位的计数,然后遍历位:

0
0 97
公告 Michael Lei · 六月 22, 2022

Hi 社区,

这是海外工程师做的一个纯浏览器的代码编辑器CloudStudio. 欢迎大家下载试用:

GitHub 下载:

https://github.com/SeanConnelly/CloudStudio

InterSystems 应用市场下载:https://openexchange.intersystems.com/package/CloudStudio

到Discord 讨论区:https://discord.gg/ZnvdMywsjP
 

Docker 支持与在线Demo:

要求

已安装 git 和 Docker desktop .

安装

Clone/git 把 repo 导入任何本地目录

git https://github.com/rcemper/Dataset-OEX-reviews.git

启动IRIS容器:

docker-compose up -d --build

如何测试

http://localhost:42773/cloudstudio/CloudStudio.Index.cls

或使用在线Demo 

Demo 视频:https://www.youtube.com/watch?v=Am6QAvrPPPg

 

0
0 137
文章 姚 鑫 · 六月 21, 2022 3m read

第六章 操作位和位串(二)

将位序列存储为整数

如果要将一系列布尔参数传递给方法,一种常见的方法是将它们作为编码为单个整数的位序列传递。

例如,Security.System.ExportAll() 方法用于从 IRIS 实例中导出安全设置。如果查看此方法的类引用,将看到它的定义如下:

classmethod ExportAll(FileName As %String = "SecurityExport.xml", 
ByRef NumExported As %String, Flags As %Integer = -1) as %Status

第三个参数 Flags 是一个整数,其中每个位代表一种可以导出的安全记录。

0
0 111
文章 Michael Lei · 六月 21, 2022 3m read

如果您使用InterSystems技术开发了自己的网络应用,现在想在客户端进行验证码验证,以确定用户真实性使其更加安全。有一些现代框架可以解决验证码的问题,然而它们中的大多数需要互联网接入来生成代码,有时实施起来很复杂。考虑到图像识别已经非常成熟,您可以参考本文为基本例子。这就是为什么现在倾向于看到更多的模式识别验证码而不是单纯的阅读验证码。(例如,点击所有有店面的图片)。如果你需要更复杂的东西,请继续开发,改进这个代码并分享它。 继续阅读以了解如何使用这个基本的例子:

Demo.Captcha class

使用这个类,你可以在一个物理目录上创建验证码图像文件,以便在你的应用程序上显示。请注意,创建图像的目录必须是可用的,以便你的Web应用程序访问这些图像。要创建验证码图像,请调用以下方法,将完整的文件名作为一个参数:

创建 image 文件

0
0 122
文章 姚 鑫 · 六月 20, 2022 4m read

第五章 操作位和位串

有时可能希望在基于数据平台的应用程序中存储一系列相关的布尔值。可以创建许多布尔变量,也可以将它们存储在数组或列表中。或者可以使用称为“位串”的概念,它可以定义为位序列,首先呈现最低有效位。位串允许您以非常有效的方式存储此类数据,无论是在存储空间还是处理速度方面。

位串可以以两种方式之一存储,作为压缩字符串或整数。如果在没有上下文的情况下听到术语“位串”,则表示位序列存储为压缩字符串。本文向介绍了这两种类型的位串,然后介绍了一些可用于操作它们的技术。

将位序列存储为位串

存储位序列的最常见方式是在位串中,这是一种特殊的压缩字符串。除了节省存储空间外,还可以使用 ObjectScript 系统函数有效地操作位串。

这样的系统函数是 $factor,它将整数转换为位串。我们可以通过执行以下语句将整数 11744 转换为位串:

set bitstring = $factor(11744)

要查看位串内容的表示,可以使用 zwrite 命令:

zwrite bitstring
bitstring=$zwc(128,4)_$c(224,45,0,0)/*$bit(6..9,11,12,14)*/
0
0 98
文章 Jingwei Wang · 六月 20, 2022 8m read

安装Arbiter

为了将自动故障转移扩展到尽可能广泛的故障情况,InterSystems建议你为每个镜像配置一个仲裁机。

要充当仲裁者,系统必须有一个正在运行的ISCAgent进程。由于ISCAgent是与InterSystems IRIS一起安装的,任何承载一个或多个InterSystems IRIS实例的系统都符合这一要求,可以被配置为仲裁者而无需进一步准备;但是,承载一个或多个故障转移或DR异步镜像成员的系统不应该被配置为该镜像的仲裁者。

没有托管InterSystems IRIS实例的系统可以通过安装Arbiter方式的作为仲裁者。请从InterSystems公司下载适合你的仲裁者系统平台的ISCAgent安装包,然后,安装ISCAgent。

注意:Arbiter的版本要和InterSystems IRIS安装版本保持一致。

在Windows上安装Arbiter

在Windows系统上,只需执行安装文件,例如ISCAgent-2020.1.0.540.0-win_x64.exe。

在Linux上安装Arbiter

0
1 603
文章 姚 鑫 · 六月 19, 2022 3m read

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

避免死锁

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

举个例子:

  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

锁的实际用途

0
0 151
文章 姚 鑫 · 六月 17, 2022 7m read

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

升级锁

使用升级锁来管理大量锁。当锁定数组的节点时,它们是相关的,特别是当将多个节点锁定在同一下标级别时。

当给定进程在同一数组中的给定下标级别创建了超过特定数量(默认为 1000)的升级锁时, 将删除所有单独的锁名称并用新锁替换它们。新锁位于父级,这意味着数组的整个分支被隐式锁定。示例(如下所示)演示了这一点。

应用程序应在合适的情况下尽快释放特定子节点的锁(与非升级锁完全相同)。当释放锁时, 会减少相应的锁计数。当的应用程序移除足够多的锁时,会移除父节点上的锁。第二小节显示了一个示例。

锁升级示例

假设有 1000^MyGlobal("sales","EU",salesdate) 形式的锁,其中 salesdate 表示日期。锁表可能如下所示:

注意 Owner 19776 的条目(这是拥有锁的进程)。 ModeCount 列指示这些是共享的、升级的锁。

当同一进程试图创建另一个相同形式的锁时, 会升级它们。它会移除这些锁并用名称为 ^MyGlobal("sales","EU") 的单个锁替换它们。现在锁表可能如下所示:

ModeCount 列表明这是一个共享的升级锁,它的计数是 1001

请注意以下关键点:

0
0 100
文章 姚 鑫 · 六月 16, 2022 4m read

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

关于零超时的说明

如上所述,如果您将 timeout 指定为 0, 会添加锁。但是,如果使用零超时锁定父节点,并且已经在子节点上锁定,则忽略零超时并使用内部 1 秒超时。

删除锁

要删除默认类型的锁,请使用 LOCK 命令,如下所示:

LOCK -lockname

如果执行此命令的进程拥有具有给定名称的锁(默认类型),则此命令将删除该锁。或者,如果进程拥有多个锁(默认类型),此命令将删除其中一个。

或者删除另一种类型的锁:

LOCK -lockname#locktype

其中 locktype 是一串锁类型代码。

LOCK 命令的其他基本变体

为了完整起见,本节讨论 LOCK 命令的其他基本变体:使用它来创建简单的锁并使用它来删除所有锁。这些变化在实践中并不常见。

创建简单的锁

对于 LOCK 命令,如果省略 + 运算符,LOCK 命令首先会删除该进程持有的所有现有锁,然后尝试添加新锁。在这种情况下,锁称为简单锁而不是增量锁。一个进程可以拥有多个简单的锁,如果该进程使用如下语法同时创建它们:

 LOCK (^MyVar1,^MyVar2,^MyVar3)

简单的锁在实践中并不常见,因为通常需要持有多个锁并在代码的不同步骤中获取它们。因此使用增量锁更实用。

0
0 64
文章 姚 鑫 · 六月 15, 2022 5m read

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

任何多进程系统的一个重要特征是并发控制,即防止不同进程同时更改特定数据元素的能力,从而导致损坏。 提供了一个锁管理系统。本文提供了一个概述。

此外,%Persistent 类提供了一种控制对象并发访问的方法,即 %OpenId() 的并发参数和该类的其他方法。这些方法最终使用本文讨论的 ObjectScript LOCK 命令。所有持久对象都继承这些方法。同样,系统会自动对 INSERTUPDATEDELETE 操作执行锁定(除非指定 %NOLOCK 关键字)。

%Persistent 类还提供方法 %GetLock()%ReleaseLock()%LockId()%UnlockId()%LockExtent()%UnlockExtent()

介绍

基本的锁定机制是 LOCK 命令。此命令的目的是延迟一个进程中的活动,直到另一个进程发出可以继续进行的信号。

锁本身并不能阻止活动行为。锁定仅按约定起作用:它要求相互竞争的进程都使用相同的锁定名称实现锁定。例如,下面描述了一个常见的场景:

0
0 97
文章 姚 鑫 · 六月 14, 2022 5m read

第九章 其他参考资料(二)

特殊变量 (SQL)

系统提供的变量。

$HOROLOG
$JOB
$NAMESPACE
$TLEVEL
$USERNAME
$ZHOROLOG
$ZJOB
$ZPI
$ZTIMESTAMP
$ZTIMEZONE
$ZVERSION

SQL直接支持许多对象脚本特殊变量。这些变量包含系统提供的值。只要可以在SQL中指定文字值,就可以使用它们。

SQL特殊变量名不区分大小写。大多数可以使用缩写来指定。

0
0 95
文章 Lilian Huang · 六月 14, 2022 3m read

这篇文章是上一篇文章的延续https://cn.community.intersystems.com/post/首次使用intersystems-iris-互操作性-一个production是什么?

在上一篇文章:https://cn.community.intersystems.com/post/首次使用intersystems-iris-互操作性-一个production是什么?  我们查验了什么是Production. 我们运行了示例代码,并在Visual Trace 页面查验了如何将流动消息的内容引入进Production中。

本文将回顾消息messages的概念和定义,和消息如何在系统集成所需的开发内容中用于组件之间发送和接收数据。

在创建一个Message消息之前,让我们回顾一个案例研究。

一家公司经营着一个购物网站,并且正在为了适应季节而改变显示的产品信息顺序。

0
0 211