Use ReadIsolation instead of LockTable

Properties
LC0031 Info Design Code Fix Ignore Obsolete

LockTable() is the traditional way to acquire an update lock before reading or modifying records. The problem is that it modifies global session state: once called on any record variable, every subsequent read against that table — on any variable instance — acquires an update lock for the remainder of the transaction. An event subscriber, a FlowField calculation, or unrelated code further down the call stack can end up locking rows it never intended to touch.

ReadIsolation, introduced in Business Central 2023 wave 1 (v22), sets the isolation level on the specific record variable only. Other variables of the same table remain unaffected, keeping lock scope tight and predictable.

There is another reason to make the switch: tri-state locking (default from v25 onward) falls back to pessimistic two-state locking the moment LockTable() is called anywhere in the transaction. Replacing LockTable() with ReadIsolation preserves the tri-state benefits — fewer locks, higher concurrency, and fewer lock timeouts across the system.

Example

The following procedure locks the entire G/L Entry table for the rest of the transaction just to read the last entry number:

procedure GetNextEntryNo(): Integer
var
    GLEntry: Record "G/L Entry";
begin
    GLEntry.LockTable(); // Use ReadIsolation instead of LockTable [LC0031]
    GLEntry.FindLast();
    exit(GLEntry."Entry No." + 1);
end;

With ReadIsolation, only this specific variable acquires the lock. Any other code reading from G/L Entry later in the transaction remains unaffected:

procedure GetNextEntryNo(): Integer
var
    GLEntry: Record "G/L Entry";
begin
    GLEntry.ReadIsolation(IsolationLevel::UpdLock);
    GLEntry.FindLast();
    exit(GLEntry."Entry No." + 1);
end;

See also