Bound commit checkpoints by key range

Use a capped ordered query to discover each checkpoint watermark before locking and processing only that key range.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 85be3fc4-5253-47b8-ba1b-6b8fd188fcea
This commit is contained in:
Jesper Schulz-Wedde 2026-07-14 11:48:01 +02:00
parent bad62d2763
commit e374a8a4b8
2 changed files with 43 additions and 12 deletions

View file

@ -1,3 +1,17 @@
query 50127 "Perf Customer Chunk"
{
QueryType = Normal;
OrderBy = ascending(CustomerNo);
elements
{
dataitem(Customer; Customer)
{
column(CustomerNo; "No.") { }
}
}
}
codeunit 50128 "Perf Sample CommitInLoop Good"
{
procedure NormalizeCustomerNames()
@ -5,28 +19,45 @@ codeunit 50128 "Perf Sample CommitInLoop Good"
LastCustomerNo: Code[20];
begin
// The outer loop owns checkpoints; the per-row loop contains no Commit.
while NormalizeNextChunk(LastCustomerNo, 500) do
while NormalizeNextChunk(LastCustomerNo) do
Commit();
end;
local procedure NormalizeNextChunk(var LastCustomerNo: Code[20]; ChunkSize: Integer): Boolean
local procedure NormalizeNextChunk(var LastCustomerNo: Code[20]): Boolean
var
Customer: Record Customer;
RowsInChunk: Integer;
CustomerChunk: Query "Perf Customer Chunk";
FirstCustomerNo: Code[20];
LastChunkCustomerNo: Code[20];
begin
Customer.SetCurrentKey("No.");
CustomerChunk.TopNumberOfRows(500);
if LastCustomerNo <> '' then
Customer.SetFilter("No.", '>%1', LastCustomerNo);
if not Customer.FindSet(true) then
CustomerChunk.SetFilter(CustomerNo, '>%1', LastCustomerNo);
CustomerChunk.Open();
if not CustomerChunk.Read() then begin
CustomerChunk.Close();
exit(false);
end;
FirstCustomerNo := CustomerChunk.CustomerNo;
repeat
LastChunkCustomerNo := CustomerChunk.CustomerNo;
until not CustomerChunk.Read();
CustomerChunk.Close();
Customer.SetCurrentKey("No.");
Customer.SetRange("No.", FirstCustomerNo, LastChunkCustomerNo);
if not Customer.FindSet(true) then begin
LastCustomerNo := LastChunkCustomerNo;
exit(true);
end;
repeat
Customer.Name := UpperCase(Customer.Name);
Customer.Modify();
LastCustomerNo := Customer."No.";
RowsInChunk += 1;
until (RowsInChunk >= ChunkSize) or (Customer.Next() = 0);
until Customer.Next() = 0;
LastCustomerNo := LastChunkCustomerNo;
exit(true);
end;
}