Skip to main content
Previous sectionNext section

^$LOCK

Provides lock name information.

Synopsis

^$|nspace|LOCK(lock_name,info_type,pid)
^$|nspace|L(lock_name,info_type,pid)

Parameters

Parameter Description
|nspace|
or
[nspace]
Optional — An extended SSVN reference, either an explicit namespace name or an implied namespace. Must evaluate to a quoted string, which is enclosed in either square brackets (["nspace"]) or vertical bars (|"nspace"|). Namespace names are not case-sensitive; they are stored and displayed in uppercase letters.
lock_name An expression that evaluates to a string containing a lock variable name, either subscripted or unsubscripted. If a literal, must be specified as a quoted string.
info_type Optional — A keyword specifying what type of information about lock_name to return. Must be specified as a quoted string. The available options are "OWNER", "FLAGS", "MODE", and "COUNTS".
pid Optional — For use with the "COUNTS” keyword. An integer that specifies the process ID of the owner of the lock. If specified, at most one list element is returned for "COUNTS”. If omitted (or specified as 0), a list element is returned for each owner holding the specified lock. pid has no effect on the other info_type keywords.

Description

The ^$LOCK structured system variable returns information about locks in the current namespace or a specified namespace on the local system. You can use ^$LOCK in two ways:

  • With info_type as a stand-alone function that returns information on a specified lock.

  • Without info_type as an argument to the $DATA, $ORDER, or $QUERY functions.

Note:

^$LOCK retrieves lock table information from the lock table on the local system. It will not return information from a lock table on a remote server.

^$LOCK in an ECP Environment

  • Local System: When invoking ^$LOCK for locks held by the local system, the behavior of ^$LOCK is the same as without ECP, with one exception: the "FLAGS" info_type returns an asterisk (*), signifying that the lock is in an ECP environment. This means that remote Caché instances have the ability to hold the lock once it is released.

  • Application Server: When invoking ^$LOCK on an application server for a lock held on another server via ECP (either a data server or another application server), ^$LOCK does not return any information. Note that this is the same behavior as if the lock did not exist.

  • Data Server: When invoking ^$LOCK on a data server for a lock held by an application server, ^$LOCK will have slightly different behavior than on a local system, as follows:

    • "OWNER": If the lock is held by an application server connected to a data server that invokes ^$LOCK, ^$LOCK(lockname, "OWNER") returns “ECPConfigurationName:MachineName:InstanceName” for the instance holding the lock, but does not identify the specific process holding the lock.

    • "FLAGS": If the lock is held by an application server connected to a data server that invokes ^$LOCK, ^$LOCK(lockname, "FLAGS") for an exclusive lock returns a “Z” flag. This “Z” signifies a type of legacy lock that is no longer used in Caché except in ECP environments.

    • "MODE": If the lock is held by an application server connected to a data server that invokes ^$LOCK, ^$LOCK(lockname, "MODE") for an exclusive lock returns “ZAX” instead of “X”. ZA is a type of legacy lock that is no longer used in Caché except in ECP environments. For a shared lock, ^$LOCK(lockname, "MODE") returns “S”, the same as for a local lock.

Parameters

nspace

This optional parameter allows you to specify a global in another namespace by using an extended SSVN reference. You can specify the namespace name either explicitly, as a quoted string literal or as a variable, or by specifying an implied namespace. Namespace names are not case-sensitive. You can use either bracket syntax ["USER"] or environment syntax |"USER"|. No spaces are allowed before or after the nspace delimiters.

You can test whether a namespace is defined by using the following method:

   WRITE ##class(%SYS.Namespace).Exists("USER"),!  ; an existing namespace
   WRITE ##class(%SYS.Namespace).Exists("LOSER")   ; a non-existent namespace
Copy code to clipboard

You can use the $NAMESPACE special variable to determine the current namespace. The preferred way to change the current namespace is NEW $NAMESPACE then SET $NAMESPACE="nspacename".

lock_name

An expression that evaluates to a string containing a lock variable name, either subscripted or unsubscripted. A lock variable (commonly a global variable) is defined using the LOCK command.

info_type

An optional keyword specified as a quoted string.

  • "OWNER" returns the process ID (pid) of the owner(s) of the lock. If the lock is a shared lock, it returns the process IDs of all of the owners of the lock as a comma-separated list. If the specified lock does not exist, ^$LOCK returns the empty string.

  • "FLAGS" returns the state of the lock. It can return the following values: "D" — in delock pending state; "P" — in lock pending state; "N" — this is a node lock, the descendants are not locked; "Z" — this lock is in ZAX mode; "L" — lock is lost, the server no longer has this lock; "*" — this is a remote lock. If the specified lock is in a normal lock state, or does not exist, ^$LOCK returns the empty string.

  • "MODE" returns the lock mode of the current node. It returns 'X' for exclusive lock mode, 'S' for shared lock mode, and 'ZAX' for ZALLOCATE lock mode. If the specified lock does not exist, ^$LOCK returns the empty string.

  • "COUNTS" returns the lock counts for the lock, specified as a binary list structure. For an exclusive lock, the list contains one element; for a shared lock the list contains an element for each owner of the lock. You can use the pid parameter to return only the list element for a specified owner of the lock. Each element contains the owner's pid, the exclusive mode increment count, and the shared mode increment count. If both the exclusive and shared mode increment counts are 0 (or " "), the lock is in 'ZAX' mode. An increment count may be followed by a 'D' to indicate that the lock has been unlocked in the current transaction, but its release is delayed ('D') until the transaction is committed or rolled back. If the specified lock does not exist, ^$LOCK returns the empty string.

pid

A process ID of the owner of a lock. Only meaningful when using the "COUNTS" keyword. Used to limit the "COUNTS" return value to (at most) one list element. The pid is specified as an integer on all platforms. If the pid matches the process ID of an owner of lock_name ^$LOCK returns that owner's "COUNTS” list element; if pid does not match the process ID of an owner of lock_name ^$LOCK returns the empty string. Specifying pid as 0 is the same as omitting pid; ^$LOCK returns all "COUNTS" list elements. The pid parameter is permitted with the "OWNER", "FLAGS", or "MODE" keyword, but is ignored.

Examples

The following example shows the values returned by info_type keywords for an exclusive lock:

   LOCK ^B(1,1)  ; define lock
   WRITE !,"lock owner: ",^$LOCK("^B(1,1)","OWNER")
   WRITE !,"lock flags: ",^$LOCK("^B(1,1)","FLAGS")
   WRITE !,"lock mode: ",^$LOCK("^B(1,1)","MODE")
   WRITE !,"lock counts: "
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK -^B(1,1) ; delete lock
Copy code to clipboard

The following example shows how the value returned by info_type "COUNTS" changes as you increment and decrement an exclusive lock:

   LOCK ^B(1,1)      ; define exclusive lock
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK +^B(1,1) ; increment lock
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK +^B(1,1) ; increment lock again
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK -^B(1,1) ; decrement lock
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK -^B(1,1) ; decrement lock again
   ZZDUMP ^$LOCK("^B(1,1)","COUNTS")
   LOCK -^B(1,1) ; delete exclusive lock
Copy code to clipboard

The following example shows how the value returned by info_type "COUNTS" changes as you increment and decrement a shared lock:

   LOCK ^S(1,1)#"S"   ; define shared lock
   ZZDUMP ^$LOCK("^S(1,1)","COUNTS")
   LOCK +^S(1,1)#"S" ; increment lock
   ZZDUMP ^$LOCK("^S(1,1)","COUNTS")
   LOCK +^S(1,1)#"S" ; increment lock again
   ZZDUMP ^$LOCK("^S(1,1)","COUNTS")
   LOCK -^S(1,1)#"S" ; decrement lock
   ZZDUMP ^$LOCK("^S(1,1)","COUNTS")
   LOCK -^S(1,1)#"S" ; decrement lock again
   ZZDUMP ^$LOCK("^S(1,1)","COUNTS")
   LOCK -^S(1,1)#"S" ; delete shared lock
Copy code to clipboard

The following examples show how to use ^$LOCK as an argument to the $DATA, $ORDER, and $QUERY functions.

As an Argument to $DATA

$DATA(^$|nspace|LOCK(lock_name))

^$LOCK as an argument to $DATA returns an integer value that specifies whether the lock name exists as a node in ^$LOCK. The integer values that $DATA can return are shown in the following table.

Value Meaning
0 Lock name information does not exist
10 Lock name information exists

The following example tests for the existence of a lock name in the current namespace. The first WRITE returns 10 (lock name exists), the second WRITE returns 0 (lock name does not exist):

   LOCK ^B(1,2)  ; define lock
   WRITE !,$DATA(^$LOCK("^B(1,2)"))
   LOCK -^B(1,2) ; delete lock
   WRITE !,$DATA(^$LOCK("^B(1,2)"))
Copy code to clipboard

As an Argument to $ORDER

$ORDER(^$|nspace|LOCK(lock_name),direction)

^$LOCK as an argument to $ORDER returns the next or previous ^$LOCK lock name node in collating sequence to the lock name you specify. If no such lock name exists as a ^$LOCK node, $ORDER returns a null string.

Locks are returned in case-sensitive string collation order. Subscripts of a named lock are returned in subscript tree order, using numeric collation.

The direction argument specifies whether to return the next or the previous lock name. If you do not provide a direction argument, Caché returns the next lock name in collating sequence to the one you specify. For further details, refer to the $ORDER function.

The following subroutine searches the locks in the SAMPLES namespace and stores the lock names in a local array named LOCKET.

LOCKARRAY
  SET lname=""
  FOR I=1:1 {
      SET lname=$ORDER(^$|"SAMPLES"|LOCK(lname))
      QUIT:lname=""
      SET LOCKET(I)=lname
      WRITE !,"the lock name is: ",lname
  }
  WRITE !,"All lock names listed"
  QUIT
Copy code to clipboard

As an Argument to $QUERY

$QUERY(^$|nspace|LOCK(lock_name))

^$LOCK as an argument to $QUERY returns the next lock name in collating sequence to the lock name you specify. If there is no next lock name defined as a node in ^$LOCK, $QUERY returns a null string.

Locks are returned in case-sensitive string collation order. Subscripts of a named lock are returned in subscript tree order, using numeric collation.

In the following example, five global lock names are created (in random order) in the current namespace.

   LOCK (^B(1),^A,^D,^A(1,2,3),^A(1,2))
   WRITE !,"lock name: ",$QUERY(^$LOCK(""))
   WRITE !,"lock name: ",$QUERY(^$LOCK("^C"))
   WRITE !,"lock name: ",$QUERY(^$LOCK("^A(1,2)"))
Copy code to clipboard

$QUERY treats all global lock variable names, subscripted or unsubscripted, as character strings and retrieves them in string collating order. Therefore, $QUERY(^$LOCK("")) retrieve the first lock name in collating sequence order: either ^$LOCK("^A”) or a Caché-defined lock higher in the collating sequence. $QUERY(^$LOCK("^C")) retrieves the next lock name in collating sequence after the nonexistent ^C: ^$LOCK("^D”). $QUERY(^$LOCK("^A(1,2)")) retrieve ^$LOCK("^A(1,2,3)”) which follows it in collation sequence.

See Also