This document is the property of: Pegasystems Inc. 101 Main Street Cambridge, MA 02142-1590 Phone: (617) 374-9600 Fax: (617) 374-9620 www.pega.com PegaRULES Process Commander Document: Designing Applications that Ensure Data Integrity Software Version 5.1 and 5.2 Updated: January 2007
Contents
Chapter 1: About This Document.................................................................................................. 5 Who Should Read This Document......................................................................................... 6 Definition of Terms.................................................................................................................. 7 Chapter Overview ...................................................................................................................10 The Pega Developer Network (PDN) .....................................................................................11 Chapter 2: Introduction .................................................................................................................12 Overview of Object Locking ..................................................................................................13 Process Commander and Database Operations .................................................................14 When Commits Occur Programmatically......................................................................14 Activity Methods that Cause Database Operations .....................................................15 Managing Commits and Rollbacks in Custom Activities.............................................16 Process Commander Commits and Distributed Transactions...........................................20 Chapter 3: Object Locking ............................................................................................................22 About Object Locking ............................................................................................................23 Lock Keys and Lock Strings ..........................................................................................23 Lock Lifespan ..................................................................................................................24 How Locking is Enabled .................................................................................................25 How Locking is Implemented.........................................................................................25 Locking and Permissions...............................................................................................26 Database Isolation Levels ..............................................................................................26 Enabling Object Locking Manually .......................................................................................27 Before You Begin ............................................................................................................27 Configure Locking for Class Groups and Classes.......................................................29 Customize Object Locking for Cover Objects .....................................................................31 Chapter 4: Application Processing that Obtains Locks.............................................................32 Obtaining Locks for Work Objects .......................................................................................33 Assign-.acquireWorkObject Activity .............................................................................33 Work-.acquireWorkObject Activity ................................................................................35 Example: MergePage Parameter and Service Rules....................................................36 Obtaining Locks for Objects that are not Work Objects.....................................................37 Using the Obj-Open Method...........................................................................................37 Using the Obj-Open-by-Handle Method ........................................................................38 Using the Obj-Refresh-and-Lock Method......................................................................39
Managing When Object Locks are Released .......................................................................41 Reporting Locking Messages to Users ................................................................................42 About LockInfo Pages ....................................................................................................42 Using the LockInfo Harness...........................................................................................43 Capturing Lock Information and Setting it in a Page Message...................................44 Lock Status Messages....................................................................................................46 Troubleshooting and Testing ................................................................................................48 DeferredOps HTML rule ..................................................................................................48 Tracer ...............................................................................................................................48 System Locks Report......................................................................................................48
Definition of Terms
Figure 1-1 defines the terms used in this document.
Definition Mechanisms provided by your database management system that control how/whether operations access data at the same time. Database locking provides functionality such as preventing two write operations from committing changes to the same row at the same time. This kind of locking does not prevent one user from overwriting another users edits if your application allows two users to open and edit the same item at the same time.
Object locking
Ensures that while one user has a work or other object open, no other user can access that object. With object locking, the application grants the user a lock on that item when the user opens a work or other object. If a second user attempts to open and edit the same object, he or she is denied access because the object is already locked. A Java object that holds information about a user and that users session. In Process Commander, users are represented as requestors and object locks are associated with a users requestor. A parameter for the Obj-Open, Obj-Open-by-Handle, and ObjRefresh-and-Lock activity methods. When selected, this parameter instructs Process Commander to obtain an object lock on the item being opened. A parameter for the Obj-Open, Obj-Open-by-Handle, and ObjRefresh-and-Lock activity methods. When selected, this parameter instructs Process Commander to release the object lock on the item being opened when changes for the object are committed to the database. A text string that identifies an object lock. Typically, when the activity methods that save or delete objects are used, they dont cause the object to be saved or deleted immediately. Instead, these methods set up deferred write or deferred delete operations that are stored on a list of deferred operations. When a commit method is invoked, Process Commander completes all the tasks on the deferred operations list.
Requestor
Lock parameter
ReleaseOnCommit
Definition One request/response interaction between the Process Commander application and a server one HTTP communication, SOAP message and response, or Java invocation, for example. When an external system makes a service request to Process Commander, the request to the service rule and the service rules response occur within one server interaction. When an end user interacts with Process Commander from a Web browser, a server interaction is one HTTP request/response.
Transaction
A set of related operations that need to be treated as one operation for the purposes of data integrity. All of the related operations must succeed, or none of them will. A transaction ends in either a commit or a rollback. A transaction occurs within the scope of one server interaction.
Business transaction
Some subset of operations that are grouped together conceptually according to the design of the application doing the work. In the context of Process Commander, a business transaction typically means the work done with/to an object during the scope of an object lock. For example, an assignment is a business transaction. The scope of a business transaction is based on human intent. The start and end points do not mark transactional boundaries they mark the scope of an object lock. Depending on how a flow is designed, there can be several server interactions during one assignment (business transaction) because a separate server interaction occurs each time a form is refreshed. That is, a business transaction can span several server interactions.
Distributed transaction
A set of operations that include more than one resource manager and that must be treated as one operation. For example, updates to more than one database in the same transaction, or, a database transaction and the sending or receiving of a JMS message in the same transaction. To use distributed transactions, Process Commander must be deployed as an enterprise application and must be using a JDBC driver with XA support. Distributed transactions can be either bean-managed or containermanaged.
Bean-managed transaction
When running in this mode, Process Commander is in charge of the (distributed) transaction. Process Commander issues the
Term
Definition begin statement and the final commit or rollback. When deployed as an enterprise application, Process Commander is configured to run in this mode by default. That is, by default, transactions are bean-managed by Process Commander.
Container-managed transaction
When running in this mode, an external J2EE container starts and ends distributed transactions that Process Commander joins as one of the participating resources. When Process Commander finishes its work, it submits a list of operations to the resource manager(s) or it marks the transaction for rollback. If none of the resources participating in the transaction (including Process Commander) mark the transaction for rollback, the Process Commander operations are committed with the other operations within the boundaries of the transaction. If Process Commander or any of the other resources participating in the transaction marks the transaction for rollback, all the operations are rolled back. Note that only the processing managed by certain Process Commander service rule types (EJB, Java, and JMS ) can participate in container-managed transactions. For more information, see Distributed Transactions and PegaRULES Process Commander.
Transaction attribute
A setting for enterprise beans that determine how the bean or an individual business method in the bean is enlisted in containermanaged transactions. For example, whether it needs a new transaction to be started, whether it must join an existing transaction, and so on.
10
Chapter Overview
The following is a list of the remaining chapters in this document: Chapter 2, Introduction, introduces the object locking feature, describes the Process Commander deferred operations list and the activity methods that cause database operations, describes when commit operations occur as part of normal flow processing, presents information about how to write custom activities that manage commits and rollbacks, and discusses the difference between a Process Commander commit and a distributed transaction. Chapter 3, Object Locking, describes the object locking feature in detail and presents steps for enabling object locking. Chapter 4, Application Processing that Obtains Locks, describes the standard activities and activity methods to use when developing application processing that opens objects, explains how to configure applications that report locking errors to end users, and provides some troubleshooting tips.
11
12
Chapter 2 Introduction
In addition to the locking mechanisms provided by your database software, Process Commander provides object locking. While database locking ensures an object is locked during the span of a database operation (update, delete), object locking ensures that the object is locked during the entire span of time a user is working with that object. This document describes how Process Commander locks objects, how it manages commit operations, and how it manages and/or participates in transactions. It provides the information you need to design applications that take advantage of Process Commanders default object locking behavior and to configure custom processing for your applications that follows best practices: obtaining object locks as appropriate, gracefully managing errors when an object lock already exists or when commit operations fail, and so on.
13
Object locks are associated with users requestors. Requestors obtain a lock on a work or other object when the user opens an object for modification. While the requestor holds the object lock, no other requestor can make changes to that object. After the processing of the application causes the changes to be written to the database, the lock is released and the object is available to another requestor. Why isnt database locking enough? Consider the case in which two users open the same assignment, which opens the same work object. Without object locking, both users can make changes to the work object but which set of changes persist will depend on timing. The first user to finish making changes clicks the Save button. The database obtains a database lock and saves the object. Then the slower user clicks the Save button. The database obtains another database lock, saves the object, but what happens to the data entered by the first user? Very likely it is overwritten. Object locking prevents that from happening by locking the work object when the first user opened the assignment. As mentioned, object locking is enabled on work objects by default; the standard activities that provide flow processing for your applications acquire and release object locks as appropriate. However, whenever your application design needs require you to write your own custom activities that interact with work or other objects, you must configure the activities to acquire and release object locks appropriately. Chapter 3: Object Locking describes how to enable object locking for objects that are not work objects. Chapter 4: Application Processing that Obtains Object Locks describes the standard helper activities and activity methods to use when writing custom activities that open objects.
14
15
It is a best practice to create applications that take advantage of the automatic commits provided with normal flow processing. Only when your application is designed to save objects that are not work objects should you use the activity methods that cause database operations (described in the next section) in your custom activities. If your application design requires that the commit of a work object occurs during custom processing, use the standard activity Work-.CommitWithErrorHandling rather than Commit or Obj-Save activity methods.
Description Specifies that an object should be saved. By default, Obj-Save sets up a deferred write operation that does not occur until the next commit operation executes. In the very rare case that your application design requires it, you can select the WriteNow option, which forces an immediate commit of the current object. The WriteNow option does not affect any other objects with operations pending on the list of deferred operations and does not release the object lock.
Obj-Delete
Specifies that the object should be deleted. By default, this method sets up a deferred delete operation and the object is not deleted until the next
16
Activity Method
Description commit operation executes. If your application design requires it, you can select the Immediate option, which forces an immediate deletion of the object.
Commit
Specifies that all operations currently on Process Commanders deferred operations list be written to the database. If any of the operations fail, the commit will end in a rollback: all the operations will be rolled back. Note that if your application design requires you to manage the commit operation for a work object perhaps you create a button or other custom widget that commits a work object use the standard activity Work-.commitWithErrorHandling rather than the Commit method.
Rollback
Specifies that all operations currently on Process Commanders deferred operations list should be removed, or rolled back. Any objects with locks specified as ReleaseOnCommit are released with a rollback operation.
Figure 2-1. Database Operation Activity Methods The activity methods in Figure 2-1 can also be used by your applications to interact with tables in external databases. To use these methods with an external table, the appropriate class and property rules and data objects must exist. Use the Create External Data Table Rules Wizard to generate these items. For more information, see the Application Developer Help system. Process Commander also provides activity methods that invoke SQL connector rules, which interact with external databases: RDB-Save and RDB-Delete. You use SQL connector rules for stored procedures and for SQL queries that include joins or are more complex than simple read/write interactions. For more information, see the Application Developer Help system.
17
Generally speaking, activities that commit objects use the following pattern: 1. Commit the deferred operations list. 2. Evaluate the results of the commit step. 3. If the commit failed: Report errors to the clipboard page and to the Pega log. Roll back the operations.
Steps 3 through 6 of the standard activity Work-.commitWithErrorHandling, shown in Figure 2-2, illustrate the items on the preceding list.
18
operations list, display an error message, route a failed work object to a special work basket, and so on.
Note: A similarly named When rule, StepStatusGood, checks the value of the
pxMethodStatus property and returns a value of true if the value of the property begins with the word Good. That is, StepStatusGood returns a false value if the value of pxMethodStatus contains either a warning or a failure message. Use the StepStatusGood rule for evaluating whether an operation failed only if your application defines both warnings and failures as failures. If you do not consider warnings to be failures, use the StepStatusFail rule to determine whether an operation failed. The Commit step in the Work-.commitWithErrorHandling activity (Figure 2-2) evaluates two transitions before moving to the next step. The first transition uses the StepStatusFail rule to determine whether the step successfully committed the operations. If the Commit step succeeded, the activity continues to the second transition.
Reporting Errors
The Work-.commitWithErrorHandling activity also illustrates how to report errors when a commit operation fails. Step 4 uses the Page-Set-Messages activity method to write a message to the primary page of the activity. Following is the statement in the Message parameter: "Validate-SaveFailed-CommitError\t" + @getWorstMessage(tools) getWorstMessage is a utility function that extracts the value of the pxMethodStatus property. Step 5 uses a Java step to write the error message to the Pega log file. Following in the Java code in that step: oLog.fatal(myStepPage.getMessagesAll());
Note: For information about the log files, see PegaRULES Process
Commander Administration and Security, which is available on the PDN.
19
Managing a Rollback
If the Commit step in the commitWithErrorHandling activity fails that is, the StepStatusFail rule evaluates to true the activity continues. It writes a page message in step 4 and a message to the Pega log file in step 5. Then, in step 6, the commitWithErrorHandling activity invokes the Rollback method to roll back the operations that were attempted by the Commit method.
20
21
set to bean-managed. However, when an external application sends a request to one of Process Commanders transaction-aware service rule types (EJB, Java, or JMS), Process Commander can participate in container-managed distributed transactions. Note the following: If your application objects are contained in the PegaRULES database only that is, all the operations on a deferred operations list are written to the same database your application does not require the ability to participate in distributed transactions and there is no need for your Process Commander system to use database drivers with XA support. If your application does need to participate in a distributed transaction a two-phased commit, for example the transaction should be bean-managed by Process Commander, which is the default state of your Process Commander system.
For more information about bean-managed and container managed transactions, see Distributed Transactions and PegaRULES Process Commander, which is available on the PDN.
22
23
Lock Keys
The lock string of an object is determined by its lock keys. Typically, the objects lock keys are the same as the objects keys which is the value of the objects pzInsKey property. However, the design of your application might call for locking more than one class instance with a single key. As long as the classes have a common property, you could define that property as the lock key for each class (or classgroup). For example, you might design a flow in which work objects belong to a folder and only one work object from a folder can be worked on at a time. In this case, you could create a property named something like FolderKey, design the application such that the ID of the folder they belong to is stored in the FolderKey property of the work objects, and then specify the FolderKey property as the property to use as the lock key in the class groups of all the work objects that could belong to the folder.
24
Lock Strings
Lock strings are determined as follows: If lock keys are specified, the lock string includes the values of the properties identified by the lock keys in the order in which they are listed on the Locking tab of the class or class group. When lock keys are not specified, Process Commander uses the object keys as the lock keys.
The object keys are different, depending on whether the class belongs to a classgroup or not: For an object that is within the scope of a class group, the lock string is the name of the class group concatenated with the values of the properties specified as object keys on the Keys tab of the Class Group form. For example, the object key specified for the PegaSample class group in the PegaProCom RuleSet is pyID. Therefore, the lock string of a work object that belongs to the PegaSample class group would be something like PegaSample W-113. For objects that belong to classes not associated with a class group (objects that are not work objects), the lock string is the name of the class concatenated with the values of the properties specified as object keys on the Basics tab of the Class form. For example, for a class named Employee-Data with an object key of a property that holds a numeric employee ID, the lock string of an EmployeeData object would be something like Employee-Data 123456.
Lock Lifespan
Object locks have a timeout interval that is set to 120 minutes by default. When an object lock reaches the timeout threshold, the lock is not automatically released. Instead, the row in the pr_sys_locks table is updated to indicate that the current lock is expired. If a new users requestor attempts to obtain a new lock on an object with an expired lock, the new requestor takes the object lock from the old requestor. If the original user returns to the object and attempts to save it, the save fails because the users requestor no longer has an object lock on the instance. Note that an expired lock also called a soft lock. You can change the value of the lock timeout by editing the system definition data object. From the Rules by Type explorer, select SysAdmin > System. Open your system definition and specify a new value in the Lock Timeout field.
25
External Classes
You can enable object locking on classes that were generated by the External Data Table Wizard classes that represent tables in an external database. However, obtaining an object lock on an object that is stored in an external class prevents only those updates made by other requestors in the Process Commander system. It does not prevent changes being made to that object by other systems.
For information about these activities and methods, see Chapter 4: Application Processing that Obtains Object Locks, which starts on page 32.
26
27
28
29
Figure 3-1. Locks Tab of ConnectSamples-SampleWork Class Group 4. Select the Allow Locking? field. 5. Optional. If you want the lock key for the work objects that belong to this class group to be something other than the key(s) to the class group, specify the property or properties to use in the Lock Name column. Always leave the Lock Caption value blank.
30
4. Optional. If you want the lock string for the objects that belong to this class to use properties other than the key(s) to the object, specify the properties to use as the lock keys in the Lock Name column. Always leave the Lock Caption value blank.
31
3. Edit the Property-Set step so that it does not include the cover in value of the pxLockHandle property. That is, change the default value (.pxCoverInsKey == "" ? .pzInsKey : .pxCoverInsKey) to just pzInsKey as shown in Figure 3-2.
Figure 3-2. Setting pxLockHandle in the DetermineLockString Activity After you complete these steps, the lock on a work object does not also lock its cover.
32
33
If the activity you are creating Has access to the pzInsKey of the work object Does not have access to the pzInsKey of the work object but does have access to the assignment
Assign-.acquireWorkObject Activity
The Assign-.acquireWorkObject activity (Figure 4-2) checks for an existing output page and clears it if it finds one, opens the assignment page, locates the work object handle (pzInsKey), then calls and passes the handle to an internal activity that opens the work object and acquires an object lock. It also writes any errors to a page called pyOutput.
34
Figure 4-2. Assign-.acquireWorkObject For an example of how to use the Assign-.acquireWorkObject activity, locate and open the standard activity Assign-.ProcessAssignment. Figure 4-3 shows the first two steps in the ProcessAssignment activity.
Figure 4-3. Calling Assign-.AcquireWorkObject from Assign-.ProcessAssignment Step 1 uses Property-Set to set values for the activity parameters that it needs to use when it calls the Assign-.acquireWorkObject activity in step 2.
35
Work-.acquireWorkObject Activity
The Work-.acquireWorkObject activity (Figure 4-4) opens the specified work object on the specified work page, obtains a work object lock on it, writes any provided property values to the work page, and then removes the primary page. It also writes any errors to a page called pyOutput.
Figure 4-4. Work-.acquireWorkObject For an example of how to use the Work-.acquireWorkObject activity, locate and open the Work-.resumeWorkProcess activity. Figure 4-5 shows the first step in the resumeWorkProcess activity.
36
The resumeWorkProcess activity is typically used as the service activity of services that deliver information for a work object from an external system. The external system passes in the pzInsKey of the work object, the flow to resume, and so on. The service passes that information to the resumeWorkProcess activity, which uses the Work-.acquireWorkObject activity to locate the work object and obtain a work object lock for it. You would also use this activity when a flow includes logic that updates information in a work object other than the current work object. For example, perhaps a customer order work object spins off an inventory tracking work object and the status of the inventory tracking work object should be changed when the customer order work object reaches a certain point in the flow. To open the related work object the inventory tracking object you would use the Work.acquireWorkObject activity.
2. On the tab that holds the Map To data mappings (typically the Request tab, but for some rules it is the Parameters tab), map the incoming data to the ServicePage page. When the resumeWorkProcess activity calls the Work-.acquireWorkObject activity, the function used to provide the value of the MergePage parameter references the ServicePage page. When the acquireWorkObject page reaches step 9, it merges the values from the ServicePage into the pyWorkPage page.
37
38
If the object you want to open has been opened or listed previously and a page with that objects pzInsKey or pxInsHandle value is still in the clipboard, your activity can use the Obj-Open-by-Handle method. To obtain the object handle of an item, you can use the function @getPrimaryPageInstanceHandle(). It is best practice to select both the Lock and the ReleaseOnCommit parameters when you use this method. It also takes a parameter named LockInfoPage that you can use to name a page of class System-Locks to hold information about object locks. For an example, open and examine the Assign-.acquireWorkObject activity. This activity uses a Java step to obtain the handle to the assignment from the primary page (the assignment page). The Java step copies the object handle to an activity parameter named assignmentHandle. Step 3 sets values for two more activity parameters, one of which is a page name for the assignment page. Figure 4-7 shows steps 4 and 5 of Assign-acquireWorkObject.
39
Figure 4-7. Using the Obj-Open-By-Handle Activity Method Step 4 checks to verify that step 2 did, in fact, put the handle to the assignment in the assignmentHandle parameter. Then Step 5 uses the Obj-Open-By-Handle activity method to open the assignment.
40
Figure 4-8. Using the Obj-Refresh-And-Lock Activity Method Step 5 obtains a lock on the cover page and uses the LockInfoPage parameter to store any locking information that might be returned. Steps 6 and 7 manage errors. Step 8 updates the cover page, decreasing the number of open work objects by one.
41
42
When your activities detect locking errors, how you configure the activity to report the error depends on whether the processing is at a point where it can display the HTML from a harness rule. When the processing is at a point where it can display a harness, use the LockInfo page and the LockInfo harness to report the information to the user, as described in Using the LockInfo Harness on page 43. When the processing is at a point at which a harness rule cannot be displayed during the processing of a flow action, for example configure the activity to acquire the returned error message and set it on the objects page, as described in Capturing Lock Information and Setting it in a Page Message on page 44.
This section describes the LockInfo page, how to use the LockInfo harness, and how to manage locking errors when you cannot use the LockInfo harness, and provides a list of the lock status messages that can be returned from the acquireWorkObject activities.
43
named page of the class System-Locks, which represents the information from the pr_sys_locks table. You can see a LockInfo page with the Clipboard and the Tracer. It contains the following information: pxOwnerID the requestor ID of the requestor that holds the lock pxExpireDateTime the date and time the lock will expire pxUpdateOperator the operator ID of the user associated with the requestor that holds the lock pxLockHandle the lock string of the object
By convention, the LockInfo page is named LockInfo in all the standard Process Commander activities. It is best practice to name this page LockInfo in your activities, too.
44
Figure 4-9. Call the LockInfo Harness The activity calls the Assign-.acquireWorkObject activity in step 2 to open and lock the work object. Step 3 uses preconditions to determine if the object lock was successful. If the work object was already locked, step 3 runs, branching off to the DisplayLockInfo activity, which then calls the LockInfo harness (Figure 4-10).
Figure 4-10. The Work-.LockInfo Harness The LockInfo harness displays the lock string, who the object is locked by, and when the lock will expire. If the person who has the lock is the same as the person requesting the lock now, he or she can use the Release Lock button to release the old lock and continue with the current processing.
45
Figure 4-11.Managing Lock Errors Step 3 uses the Obj-Refresh-And-Lock activity method to obtain an object lock on a cover. (It sets the value the LockInfoPage parameter to LockInfo.) Step 4 uses a precondition to check the value of the pxMethodStatus property with the When rule named StepStatusFail. If StepStatusFail resolves to true, the activity continues to the next condition, one that uses the function getWorstMessageName(tools) to determine whether the error message specifies that the object is already locked. Following is the statement from the second condition: @getWorstMessageName(tools) == "Database-LockFailure-LockHeldByAnother" If this condition resolves to true at runtime, the step uses the Page-SetMessages activity method to set the following message specified in the Message parameter: "Flow_CoverLockFail\t" + pyWorkCover.pyID + "\t" + LockInfo.pxUpdateOpName If this message is triggered at runtime, the message states that the cover lock failed, provides the ID of the cover, and provides the name of the operator who currently has the lock. This information is available because the Obj-RefreshAnd-Lock method set LockInfo as the name of the LockInfo page. Then, as specified by the transition at the end of Step 4, the activity exits, returning control to the calling process.
46
Success Indicator 0 -1 -2 -3
FailureInfo No errors Work object not found. Work object open access denied Work objects lock held by another Work object modify access denied (lock fail)
Description The object was successfully locked. The work object doesnt exist it couldnt be found. The operator does not have the access rights needed to open the work object. The work object is already locked.
-4
The operator does not have the access rights needed to modify the work object, so a lock was not granted. The object is opened in a read-only state. The cover doesnt exist it couldnt be located. The operator does not have the access rights needed to open the cover. The cover is already locked. The operator does not have the access rights needed to modify the cover so a lock was not granted. The cover object is opened in a read-only state. The object is not a cover or a work object
-5 -6 -7 -8
Cover object not found Cover object open access denied Cover objects lock held by another. Cover object modify access denied (lock fail)
-9
Lockstring fail
47
FailureInfo
The object lock cant be obtained because something is wrong with the database. At this point during runtime, the assignment identified on the assignment page does not match that identified on the work objects flow page. This error indicates there is a problem in the flow rule configuration. At this point during runtime, the flow that the assignment page refers to no longer exists for the work object. This error also indicates a configuration problem with the flow. At this point during runtime, the work page has an outdated assignment handle. This can happen when developers create an activity that transfer an assignment from a work list to a workbasket, but the activity does not then update the work objects flow page. Someone deleted the flow rule while this work object was still in process. Someone deleted an assignment shape from the flow rule while this work object was still in process.
-22
-23
-24 -25
Rule-Obj-Flow no longer exists Rule-Obj-Flow exists, but the assignment shape has been deleted
48
Tracer
You can select object locking as an event to show in the Tracer. When you select the Locking option, event types of Acquired Lock and Release Lock appear in the event list. Examine these messages to determine whether a lock was needed but wasnt acquired or, perhaps, that a lock is being released before it should.