Locking [deprecated]
Last updated
Last updated
Most of the information here is deprecated. For the up-to-date method to use locking check:
Our locking system relies on logical locks instead of DB-Locks.
Advantages:
a locked row can still be updated by another process (e.g. Artikelstamm saves all columns EXCEPT durchschn_ek, while durchschn_ek is updated automatically from the warehouse routines)
when locking a row, all foreign keys are not locked (in the case of db-locks, locking an "art" entry also locks the "artgrp" entry identified by the foreign key)
Disadvantages:
if a business process does not lock an entry prior to editing it, data loss may be encountered
The locks are stored in the tlsys_lock table as a set of hybrids blocked by various transactions (and further info such as when it was acquired, by whom, etc.). Locking can only be performed when a transaction is available, hence the "Locking" property in the xTransaction object.
When attempting to lock an entry, a ResourceLockedException may occur if the entry is locked by another transaction. Repeated locking of the same hybrid on the same transaction is allowed.
When the transaction is rolled back, the locks are cleared through the fact that all entries in the tlsys_lock table are pending inserts using the current transaction. This means that if the database has hanging connections which created locks, by stopping the database all locks should be cleared automatically.
When the transaction is committed, the locks associated with the current transaction are cleared through some custom server-side code in the xTransaction object.
Usage from xTransaction; by using the "Locking" property, you can:
Lock one or more entries (may throw ResourceLockedException)
Unlock one, more entries or all entries
Get all available locks on the given transaction
Set lock checkpoint: 'remembers' the timestamp of the most recent lock (server-side timestamp)
Commit lock checkpoint: deletes all entries lower than or equal to the remembered checkpoint
Rollback lock checkpoint: deletes all entries greater than the remembered checkpoint
Usage from xDataSet:
In the DataSet Designer, on the "Tables" tab, there is the "Exkl. Locking" column that determines whether the table locks entries or not
When creating the xDataSet instance (new xDataSet("dsArt"), new dsArt(), etc.), set the "LockOnRetrieve" property to "true"
Whenever the xDataSet performes the first edit, the loaded data will be locked. Remarks:
the data will be locked either based on the "hybrid" column or on the "tableName>^<pk1>^<pk2>^...^<pkn>" auto-generated value for each retrieved row
if the locking on one of the hybrids fails, the process will be aborted and the data will not be loaded in the xDataSet (old data before retrieving is preserved)
“You can look but you can’t touch” type of locking, meaning that even if the record is locked by somebody else, you can still view the data in the module
Locking status is displayed and updated interactively
If the locking on one of the hybrids fails, the process will be aborted and the data will not be loaded in the xDataSet (old data before retrieving is preserved)
Clearing and erasing (delete) the xDataSet does not clear the associated locks
The Lock() function can be explicitly called at any point in time and locks the existing rows in the lockable tables of the xDataSet
Usage from xWindowHandlingObject:
Besides the functionality described in the xDataSet, the xWindowHandlingObject provides a set of functions that help with the process of retrieving data, such as:
DataTransition: sets a locking checkpoint, then executes the action, then commits the checkpoint if no exceptions or reverts the checkpoint if an exception occurred. Exceptions are re-thrown
DataRetrieveTransition: executes the DataTransition function; if a ResourceLockedException occurs, a custom message is shown and false is returned. If any other exception occurs, a generic error message is shown and false is returned. In case any error occurs, the local data within the DataSets is reverted to the saved state prior to the execution of the action
In the ItemChanged method, the result of the Retrieve action must be tested. If the Retrieve action was unsuccessful, the value of the control bound to the primary key must be set to the old value.
DataSaveTransition: executes the DataTransition function; if a ResourceLockedException occurs, a custom message is shown and false is returned. If any other exception occurs, a generic error message is shown and false is returned. In case any error occurs, the local data within the DataSets is reverted to the saved state prior to the execution of the action
Lock: calls the "OnLock" function. Non-overridable, used only as trigger
OnLock: calls the BusObj.Lock() function, which in turn calls .Lock() on all DataSets of the BusObj, recursively. Can be overridden
The OnSave method is called automatically from within a DataSaveTransition block. After OnSave is executed successfully the Lock function is called on the xWindowHandlingObject.
When a Retrieve occurs at the xWindowHandlingObject level, the Retrieve function of the BusinessObject as well as all other retrieve functions from the secondary BusinessObjects must be called within the "DataRetrieveTransition" function, so that if the retrieve fails, the acquired locks from the newly retrieved data are rolled back and it the retrieve succeeds, the acquired locks from the previously loaded entry are rolled back.