When using M Locks, you must use a well designed and defined locking protocol. Your locking protocol must specify guidelines for acquiring LOCKs, selecting and using timeout, releasing M Locks, defining a lock strategy according the given situation, identifying potential deadlock situations, and providing ways to avoid or recover from them. This section contains two exercises. The first exercise reinforces the concepts of GT.M LOCKs previously explained in this chapter. The second exercise describes a deadlock situation and demonstrates how one can use LKE to identify and resolve it.
Consider a situation when two users (John and Tom) have to
exclusively update a global variable ^ABC
.
Note | |
---|---|
Transaction Processing may offer a more efficient and more easily managed solution to the issue of potentially conflicting updates. For more information, see General Language Features of M chapter of the GT.M Programmer's Guide. |
At the GT.M prompt of John, execute the following commands:
GTM>lock +^ABC
This command places a GT.M LOCK on "^ABC
" (not the
global variable^ABC
). Note: LOCKs without the +/- always
release all LOCKs held by the process, so they implicitly avoid dead
locks. With LOCK +
, a protocol must accumulate LOCKs in
the same order (to avoid deadlocks).
Then execute the following command to display the status of the LOCK database.
GTM>zsystem "lke show -all"
This command produces an output like the following:
DEFAULT ^ABC Owned by PID= 3657 which is an existing process
Now, without releasing lock^ABC
, execute the
following commands at the GT.M prompt of Tom.
GTM>lock +^ABC
This command wait for the lock on resource "^ABC
"
to be released. Note that that the LOCK command does not block global
variable ^ABC
in any way. This command queues the
request for locking resource "^ABC"
in the LOCK database.
Note that you can still modify the value of global variable ^ABC
even if it is locked by John.
Now, at the GT.M prompt of John, execute the following command:
GTM>zsystem "LKE -show -all -wait"
This command produces an output like the following:
DEFAULT ^ABC Owned by PID= 3657 which is an existing process Request PID= 3685 which is an existing process
This output shows that the process belonging to John with PID 3657 currently owns the lock
for global variable ^ABC
and PID of Tom has requested
the ownership of that lock. You can use this mechanism to create an
application logic that adhere to your concurrent access
protocols.
Now, consider another situation when both these users (John and Tom) have to update two text files. While an update is in progress, a GT.M LOCK should prevent the other user from LOCKing that file. In some cases, a deadlock occurs when both users cannot move forward because they do not release their current LOCKs before adding additional LOCKs.
A deadlock situation can occur in the following situation:
John Tom LOCK +file_1 LOCK +file_2 LOCK +file_2 LOCK +file_1
Here both the users are deadlocked and neither can move forward. Note that a deadlock situation does not actually block the underlying resource.
Let us now create this situation.
At the GT.M prompt of John, execute the following commands:
GTM>set file1="file_1.txt" GTM>lock +file1 GTM>open file1:APPEND GTM>use file1 GTM>write "John",! GTM>close file1
Note that John has not released the LOCK on resource "file1".
At the GT.M prompt of Tom, execute the following commands:
GTM> set file2="file_2.txt" GTM> lock +file2 GTM> open file2:APPEND GTM> use file2 GTM>write "Tom",! GTM>close file2
Note that Tom has not released the LOCK on resource "file2".
Now, at the GT.M prompt of John, execute the following commands.
GTM>set file2="file_2.txt" GTM>lock +file2
The latter command attempts to acquire a lock on resource
file2
that is already locked by Tom.
Therefore, this results in a deadlock situation. Repeat the same
process for Tom and attempt to lock resource
file1
.
Execute the following command at LKE prompt to view this deadlock situation.
LKE>show -all -wait file1 Owned by PID= 2080 which is an existing process Request PID= 2089 which is an existing process file2 Owned by PID= 2089 which is an existing process Request PID=2080 which is an existing process
This shows a deadlock situation where neither user can proceed
forward because it is waiting for the other user to release the lock.
You can resolve this situation by clearing the locks using the
LKE CLEAR -PID
command.
Caution | |
---|---|
Avoid using the |