Business Central v27: The Real Deal with Locking, Blocking, and the Database Locks Page

Reading Time: 3 minutes

After 15 years on Business Central and NAV (and 30 in ERP overall) in factories across Greece, UK and the rest of Europe, I’ll tell you something most consultants still don’t understand properly: locking and blocking are usually not a SQL Server problem. They are application design problems.

Here is the part many people don’t want to hear: Business Central’s locking model is actually pretty solid. In most cases the real problem is not Microsoft. It is custom AL code, sloppy integrations, or long transactions that should never have been written as one big piece.

I’ve seen the same story many times, especially in Greek companies. The customer calls and says “the system is slow again.” Everyone blames BC. Three hours later we find a custom posting routine holding thousands of row locks while it waits for a vendor API to answer. Usually the fix is only four or five lines of better code.

The funny thing is Microsoft actually improved concurrency a lot in recent versions, specially v27. The platform is better than many people think, but bad AL code can still destroy performance very quickly.

Locking vs Blocking

Locking vs Blocking
Locking vs Blocking

Quick refresher because people mix these up constantly:

  • Locking = normal behaviour. SQL protecting data consistency.
  • Blocking = the real pain. One session waiting because something is already locked.
  • Deadlock = the nightmare. Two sessions waiting for each other and SQL kills one process.

Business Central mostly uses row-level locking, which is good. But if your code touches too many records at once, SQL escalates to page or table locks. That’s when users start screaming and the whole factory feels frozen.

What’s New in v27 That Really Helps

Microsoft made some very useful improvements:

  • Tri-state locking is now the default (optimistic concurrency).
  • Record.ReadIsolation lets you lock only the exact record you need.
  • Better telemetry and parallel posting options.
  • Better handling for background sessions.

Practical advice from the field: If you are still using LockTable() everywhere like in the old NAV days, please stop. It destroys all the new optimistic behaviour for no reason.

My Favourite Feature in v27: The Database Locks Page

Just press Alt+Q and type “Database Locks”. You immediately see who is holding locks and who is waiting.

Before v27, when a customer in Greece called me saying the system was frozen, I had to ask IT for SQL Server Management Studio access. Now any administrator can check it directly inside BC.

One important thing people miss: it’s only a snapshot, not real-time monitoring. You need to refresh it during active blocking issues. But together with telemetry it helps you find the guilty object very quickly.

The AL Patterns That Matter Most

After all these years, these are the habits that prevent 80% of the blocking problems I see.

1. Keep write transactions short

The single biggest mistake I see: one giant transaction processing thousands of records.

Bad way (one big transaction):

if Item.FindSet() then
    repeat
        Item."Last Updated" := Today;
        Item.Modify();
    until Item.Next() = 0;

Commit;  // only at the end

Better way:

Counter := 0;

if Item.FindSet() then
    repeat
        Item."Last Updated" := Today;
        Item.Modify();
        Counter += 1;
        if Counter mod 100 = 0 then
            Commit;   // release locks every 100 records
    until Item.Next() = 0;

Commit;

This small change has solved many performance issues for my customers.

2. Use surgical locking instead of LockTable()

Some developers still use LockTable() like it’s candy. Usually unnecessary.

Don’t do this:

Customer.LockTable();
Customer.FindSet();

Do this instead:

Customer.SetRange("No.", CustomerNo);
Customer.ReadIsolation := IsolationLevel::UpdLock;
Customer.FindFirst();

Much cleaner and less destructive for concurrency.

3. Never call HTTP inside a transaction

This one drives me crazy because I still see it in 2025. Always commit your data first, then make the external call. Otherwise one slow vendor API can freeze the entire system.

4. Watch out for number series bottlenecks

If you’re running high-volume document creation and the No. Series Line is a chokepoint, look at “Allow Gaps in Nos.” for non-regulated documents. It removes the single-file queue on number assignment. Don’t use it where regulation requires continuous numbering (Greek invoicing rules, for example, won’t tolerate gaps).

My Practical Rules After 15 Years on BC

Honestly the rules are pretty simple:

  • Keep transactions short. Commit early, commit often.
  • Lock only records you truly need.
  • Never wait on external systems while holding locks.
  • Commit strategically, not emotionally.
  • Stop blaming SQL Server for bad AL design.

The new Database Locks page in v27 is excellent for diagnosis, but it won’t save badly designed customisations. The real solution is still in the quality of your AL code. Write clean code and you will rarely need to open that page at all.

If you are having blocking issues, the answer is almost never “buy more hardware.” It is usually one badly designed transaction holding too much for too long.


Discover more from Inside Business Central

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top