Managing the Lock Table
InterSystems IRIS maintains a system-wide, in-memory table that records all current locks and the processes that own them. This table, the lock table, is accessible via the Management Portal, where you can view the locks and (in rare cases, if needed) remove them. This topic discusses tools for viewing and managing the lock table in InterSystems products. (Also see Monitoring Locks.)
About the Lock Table
As mentioned, InterSystems IRIS maintains an in-memory table that tracks all current locks and the processes that own them. Through the Management Portal, you can view and, when necessary, remove the locks.
The lock table has a configurable maximum size. If the Lock Table exceeds that size, you will receive a message in the messages log notifying you about the capacity being reached. Find out more about this in Locking and Concurrency Control.
Viewing Locks in the Lock Table
Viewing Locks in the Management Portal
You can view all of the locks currently held or requested (waiting) system-wide using the Management Portal. From the Management Portal, select System Operation, select Locks, then select View Locks. The View Locks window displays a list of locks (and lock requests) in alphabetical order by directory (Directory) and within each directory in collation sequence by lock name (Reference). Each lock is identified by its process id (Owner), displays the user name that the operating system gave to the process when it was created (OS User Name), and has a ModeCount (lock mode and lock increment count). You may need to use the Refresh icon to view the most current list of locks and lock requests. For further details on this interface see Monitoring Locks.
Interpreting ModeCount Values in the Lock Table
ModeCount can indicate a held lock by a specific Owner process on a specific Reference. The following are examples of ModeCount values for held locks:
Some ModeCount values reflect ObjectScript-specific locking behavior. Python locks are always incremental, so some values have no direct Python equivalent.
| ModeCount | Description |
|---|---|
| Exclusive | An exclusive lock, non-escalating (iris.lock("", 0, "^a", 1) in Python or LOCK +^a(1) in ObjectScript). |
| Shared | A shared lock, non-escalating (iris.lock("S", 0, "^a", 1) in Python or LOCK +^a(1)#"S" in ObjectScript). |
| Exclusive_e | An exclusive escalating lock (iris.lock("E", 0, "^a", 1) in Python or LOCK +^a(1)#"E" in ObjectScript). |
| Exclusive_E | An exclusive/shared escalated lock, as a result of the number of locks on various nodes of this global exceeding the lock threshold. |
| Shared_e | A shared escalating lock (iris.lock("SE", 0, "^a", 1) in Python or LOCK +^a(1)#"SE" in ObjectScript). |
| Shared_E | A shared escalated lock, as a result of the number of locks on various nodes of this global exceeding the lock threshold. |
| Exclusive->Delock | An exclusive lock in a delock state. The lock has been unlocked, but release of the lock is deferred until the end of the current transaction. This can be caused by either a standard unlock (iris.unlock(['^a(1)']) in Python or LOCK -^a(1) in ObjectScript). In ObjectScript, it can also be caused by a deferred unlock (LOCK -^a(1)#"D"). |
| Exclusive,Shared | Both a shared lock and an exclusive lock (applied in any order). Can also specify escalating locks; for example, Exclusive_e,Shared_e. |
| Exclusive/n | An incremented exclusive lock (iris.lock("", 0, "^a", 1) in Python (all locks created with Python are incremental by default) or LOCK +^a(1) issued n times in ObjectScript). If the lock count is 1, no count is shown (but see below). Can also specify an incrementing shared lock; for example, Shared/2. |
| Exclusive/n->Delock | An incremented exclusive lock in a delock state. All of the increments of the lock have been unlocked, but release of the lock is deferred until the end of the current transaction. Within a transaction, unlocks of individual increments release those increments immediately; the lock does not go into a delock state until an unlock is issued when the lock count is 1. This ModeCount value, an incremented lock in a delock state, occurs when all prior locks are unlocked by a single operation, either by an argumentless LOCK command or a lock with no lock operation indicator (LOCK ^xyz(1) in ObjectScript). |
| Exclusive/1+1e | Two exclusive locks, one non-escalating, one escalating. Increment counts are kept separately on these two types of exclusive locks. Can also specify shared locks; for example, Shared/1+1e. |
| Exclusive/n,Shared/m | Both a shared lock and an exclusive lock, both with integer increments. |
A held lock ModeCount can, of course, represent any combination of shared or exclusive, escalating or non-escalating locks — with or without increments. An Exclusive lock or a Shared lock (escalating or non-escalating) can be in a Delock state.
ModeCount can indicate a process waiting for a lock, such as WaitExclusiveExact. The following are ModeCount values for waiting lock requests:
| ModeCount | Description |
|---|---|
| WaitSharedExact | Waiting for a shared lock on exactly the same lock, either held or previously-requested. For example, LOCK +^a(1,2)#"S" or iris.lock("S", 5, "^a", 1, 2) is waiting on ^a(1,2). |
| WaitExclusiveExact | Waiting for an exclusive lock on exactly the same lock, either held or previously-requested. For example, LOCK +^a(1,2) or iris.lock("", 5, "^a", 1, 2) is waiting on ^a(1,2). |
| WaitSharedParent | Waiting for a shared lock on the parent of a held or previously-requested lock. For example, LOCK +^a(1)#"S" or iris.lock("S", 5, "^a", 1) is waiting on ^a(1,2). |
| WaitExclusiveParent | Waiting for an exclusive lock on the parent of a held or previously-requested lock. For example, LOCK +^a(1) or iris.lock("", 5, "^a", 1) is waiting on ^a(1,2). |
| WaitSharedChild | Waiting for a shared lock on the child of a held or previously-requested lock. For example, LOCK +^a(1,2)#"S" or iris.lock("S", 5, "^a", 1, 2) is waiting on ^a(1). |
| WaitExclusiveChild | Waiting for an exclusive lock on the child of a held or previously-requested lock. For example, LOCK +^a(1,2) or iris.lock("", 5, "^a", 1, 2) is waiting on ^a(1). |
ModeCount indicates the lock (or lock request) that is blocking this lock request. This is not necessarily the same as Reference, which specifies the currently held lock that is at the head of the lock queue on which this lock request is waiting. Reference does not necessarily indicate the requested lock that is immediately blocking this lock request.
ModeCount can indicate other lock status values for a specific Owner process on a specific Reference. The following are these other ModeCount status values:
| ModeCount | Description |
|---|---|
| LockPending | An exclusive lock is pending. This status may occur while the server is in the process of granting the exclusive lock. You cannot delete a lock that is in a lock pending state. |
| SharePending | A shared lock is pending. This status may occur while the server is in the process of granting the shared lock. You cannot delete a lock that is in a lock pending state. |
| DelockPending | An unlock is pending. This status may occur while the server is in the process of unlocking a held lock. You cannot delete a lock that is in a lock pending state. |
| Lost | A lock was lost due to network reset. |
Select Display Owner’s Routine Information to enable the Routine column, which provides the name of the routine that the owner process is executing, prepended with the current line number being executed within that routine.
Select Show SQL Options, and then select a namespace from the Show SQL Table Names for Namespace list, to enable the SQL Table Name column. This column provides the name of the SQL table associated with each process in the selected namespace. If the process is not associated with an SQL table, this column value is empty.
The View Locks window cannot be used to remove locks.
Viewing Locks with ^LOCKTAB
You can view current lock table entries using the ^LOCKTAB utility in the %SYS namespace.
To display locks in read-only mode, use:
DO View^LOCKTAB
This form displays the current contents of the lock table; it does not provide options to modify or delete locks.
You can also use the full utility:
DO ^LOCKTAB
This displays the same lock information but also includes administrative commands. For details on deleting locks using this utility, see Removing Locks.
The display includes information about each lock, such as the owning process, lock mode, and any waiting processes. For example:
%SYS>DO ^LOCKTAB
Node Name: MYCOMPUTER
LOCK table entries at 07:22AM 01/13/2018
16767056 bytes usable, 16774512 bytes available.
Entry Process X# S# Flg W# Item Locked
1) 4900 1 ^["^^c:\intersystems\iris\mgr\"]%SYS("CSP","Daemon")
2) 4856 1 ^["^^c:\intersystems\iris\mgr\"]ISC.LMFMON("License Monitor")
3) 5016 1 ^["^^c:\intersystems\iris\mgr\"]ISC.Monitor.System
4) 5024 1 ^["^^c:\intersystems\iris\mgr\"]TASKMGR
5) 6796 1 ^["^^c:\intersystems\iris\mgr\user\"]a(1)
6) 6796 1e ^["^^c:\intersystems\iris\mgr\user\"]a(1,1)
7) 6796 2 1 ^["^^c:\intersystems\iris\mgr\user\"]b(1)Waiters: 3120(XC)
8) 3120 2 ^["^^c:\intersystems\iris\mgr\user\"]c(1)
9) 2024 1 1 ^["^^c:\intersystems\iris\mgr\user\"]d(1)
Command=>
In this display:
-
The X# column lists exclusive locks held, with the number indicating the lock increment count. The “e” suffix indicates that the lock is defined as escalating. The “D” suffix indicates that the lock is in a delock state.
-
The S# column lists shared locks held, with the number indicating the lock increment count. The “e” suffix indicates that the lock is defined as escalating. The “D” suffix indicates that the lock is in a delock state.
-
The Flg column indicates whether the lock is in a pending state.
-
The W# column shows the number of processes waiting for the lock.
As shown in the above display, process 6796 holds an incremented shared lock ^b(1). Process 3120 has one lock request waiting for this lock. The lock request is for an exclusive (X) lock on a child (C) of ^b(1).
Enter a question mark (?) at the Command=> prompt to display help for interpreting the output.
Enter Q to exit the utility.
Viewing Locks Programmatically
You can query lock table information programmatically using the %SYS.LockQueryOpens in a new tab class, which lets you read lock table information. The SYS.LockOpens in a new tab class, available in the %SYS namespace, provides related administrative and configuration methods. These queries are useful for identifying lock owners, waiting processes, and potential lock conflicts when diagnosing concurrency issues.
For more information on these classes, see the class reference.
Deleting Locks
There are multiple ways to remove (delete) locks from the lock table as an administrative action.
Rather than removing a lock, the best practice is to identify and then terminate the process that created the lock. Removing a lock can have a severe impact on the system, depending on the purpose of the lock.
Removing Locks in the System Management Portal
To remove (delete) locks currently held on the system, go to the Management Portal, select System Operation, select Locks, then select Manage Locks. For the desired process (Owner) click either Remove or Remove All Locks for Process.
Removing a lock deletes it from the lock table, regardless of lock type or increment level, and makes it available to other processes. For details on how this affects lock state and waiting processes, see Locking and Concurrency Control.
You can also remove locks using the SYS.Lock.DeleteOneLock()Opens in a new tab and SYS.Lock.DeleteAllLocks()Opens in a new tab methods.
Removing a lock requires WRITE permission. Lock removal is logged in the audit database (if enabled); it is not logged in messages.log.
For details on how lock removal affects lock state and queues, see Locking and Concurrency Control.
Removing Locks with ^LOCKTAB
You can remove (delete) locks using the ^LOCKTAB utility in the %SYS namespace.
To access lock removal commands, run:
DO ^LOCKTAB
The ^LOCKTAB utility provides interactive commands for:
-
Deleting an individual lock
-
Deleting all locks owned by a specified process
-
Deleting all locks on the system
Enter a question mark (?) at the Command=> prompt to display the available commands and their usage.
You cannot delete a lock that is in a lock pending state, as indicated by the Flg column (described in Viewing Locks with the ^LOCKTAB Utility).
For details on how lock removal affects lock behavior and waiting processes, see Locking and Concurrency Control.
Enter Q to exit the utility.
See Also
-
Details of Lock Requests and Deadlocks