diff --git a/Documentation-develop/RECORD_LOCK.md b/Documentation-develop/RECORD_LOCK.md new file mode 100644 index 0000000000000000000000000000000000000000..0b811f49d24bb670dffaeeaf13b0759202dea4ce --- /dev/null +++ b/Documentation-develop/RECORD_LOCK.md @@ -0,0 +1,42 @@ +<!-- -*- markdown -*- --> + +# Record locking + +## Concept: Late locking + +* A lock is required on first modification. +* Multiple forms might open the same record, all seems to have write access. The first one who modifies the record + get the lock, all following will switch to form=readonly on their first try to modify the record. + +## Lock mode: Exclusive + +* A lock can't be overwritten. + +## Lock mode: Advisory + +* A lock can be ignored. +* Last save win's. + +## Lock mode: None + +* No locking at all. + +# Workarounds + +* At least one Browser (FF 71, maybe other in the future too), do not allow to wrap the 'leave page' dialog anymore. + This might result in stale lock files (modified record, click on browser tab close or any link), cause the lock + logic does not know that the user leaves the page. + + * Workaround: before 'do you want to leave the page' appears, the lock is released, independent if the user answers 'no'. + As soon as the users modifies the record again, a new lock is acquired. This is better than a stale record lock. + +* Reload a page (F5) on a modified record, opens the form in readonly mode (record lock found). + + * Reason: the lock release is fired by the browser AFTER form load - than the lock-logic reports 'record is already locked'. + * Workaround: with the above workaround, this does not happen anymore. Nevertheless, a 'tabUniqId' has been implemented. + That one is saved as record lock and a page reload origin can be identified as the same tab as where the lock has been + acquired. + += State Diagram = + +See `Documentation-develop/diagram` for a state diagram. diff --git a/Documentation/Manual.rst b/Documentation/Manual.rst index 227ea5b7afede052d21c20b7982bb3758ca23159..7a854f2734eb278bff8d7621d2db16487369beb0 100644 --- a/Documentation/Manual.rst +++ b/Documentation/Manual.rst @@ -2255,7 +2255,7 @@ If a timeout expires, the lock becomes invalid. During the next change in a form A lock is assigned to a record of a table. Multiple forms, with the same primary table, uses the same lock for a given record. -If a `Form` acts on further records (e.g. via FE action), those records are not protected by this basic record locking. +If a `Form` acts on further records (e.g. via FE action), those further records are not protected by this basic record locking. If a user tries to delete a record and another user already owns a lock on that record, the delete action is denied. diff --git a/extension/Classes/Core/Constants.php b/extension/Classes/Core/Constants.php index a6fb4f89fb51eca84f89d6838e2bbe5da5b196e9..c4bcc9a0fade0d6c4b50a8bb92c0a615c85f64fb 100644 --- a/extension/Classes/Core/Constants.php +++ b/extension/Classes/Core/Constants.php @@ -1816,7 +1816,7 @@ const DIRTY_API_ACTION_EXTEND = 'extend'; const LOCK_NOT_FOUND = 0; const LOCK_FOUND_OWNER = 1; const LOCK_FOUND_CONFLICT = 2; -const TAB_UNIQ_ID = 'tabUniqId'; // Currently only only a uniq identifier: no values stored behind the identifier - might change. +const TAB_UNIQ_ID = 'tabUniqId'; // Uniq identifier per tab: no values stored behind the identifier - might change. // AutoCron const AUTOCRON_MAX_AGE_MINUTES = 10; diff --git a/extension/Classes/Core/Form/Dirty.php b/extension/Classes/Core/Form/Dirty.php index 970f68fb6c5c4630d77257386f3799ed970c32b6..b8039fa2a80f20edd608b57122a61d29f3401e83 100644 --- a/extension/Classes/Core/Form/Dirty.php +++ b/extension/Classes/Core/Form/Dirty.php @@ -146,7 +146,7 @@ class Dirty { } /** - * Tries to get a 'DirtyRecord'. Returns an array (becomes JSON) about success or failure. + * Tries to get a lock ('dirty record'). Returns an array (becomes JSON) about success or failure. * * @param int $recordId * @param array $tableVars