mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-07 15:46:55 +01:00
PR #152 round 3 (JesperSchulz): - The good sample's OnAfterInsertEvent subscriber still raced on the shared "Transfer Setup Good" singleton (Get/increment/Modify); AutoIncrement only protected the request key. Added TransferSetup.LockTable() before Get() to serialize concurrent background sessions. - Promoted changecompany-runs-triggers-in-the-calling-company from community/knowledge/events/ to microsoft/knowledge/events/, and wired ChangeCompany/StartSession/RunTrigger tokens plus a targeted detection cue into microsoft/skills/review/al-events-review.md so a diff containing the anti-pattern reliably worklists this article, preserving the documented RunTrigger=false hand-off exception. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
84 lines
2.4 KiB
AL
84 lines
2.4 KiB
AL
codeunit 50100 "Transfer Request Good"
|
|
{
|
|
// Self-contained demonstration of the best practice. Not derived from base-app source.
|
|
procedure RequestFromCompany(TargetCompany: Text[30]; ItemNo: Code[20]; Quantity: Decimal)
|
|
var
|
|
TransferRequest: Record "Transfer Request Good";
|
|
SessionId: Integer;
|
|
begin
|
|
TransferRequest.Init();
|
|
TransferRequest."Item No." := ItemNo;
|
|
TransferRequest.Quantity := Quantity;
|
|
// The insert runs inside TargetCompany, so OnInsert and the subscriber read that company's setup.
|
|
StartSession(SessionId, Codeunit::"Transfer Request Create Good", TargetCompany, TransferRequest);
|
|
end;
|
|
}
|
|
|
|
codeunit 50102 "Transfer Request Create Good"
|
|
{
|
|
TableNo = "Transfer Request Good";
|
|
|
|
trigger OnRun()
|
|
begin
|
|
// "Entry No." is AutoIncrement, so concurrent background sessions in TargetCompany never race on the same value.
|
|
Rec.Insert(true);
|
|
end;
|
|
}
|
|
|
|
table 50100 "Transfer Request Good"
|
|
{
|
|
DataClassification = CustomerContent;
|
|
|
|
fields
|
|
{
|
|
field(1; "Entry No."; Integer) { AutoIncrement = true; }
|
|
field(2; "Item No."; Code[20]) { }
|
|
field(3; Quantity; Decimal) { }
|
|
field(4; "Location Code"; Code[10]) { }
|
|
}
|
|
|
|
keys
|
|
{
|
|
key(PK; "Entry No.") { Clustered = true; }
|
|
}
|
|
|
|
trigger OnInsert()
|
|
var
|
|
TransferSetup: Record "Transfer Setup Good";
|
|
begin
|
|
TransferSetup.Get();
|
|
"Location Code" := TransferSetup."Default Location Code";
|
|
end;
|
|
}
|
|
|
|
table 50101 "Transfer Setup Good"
|
|
{
|
|
DataClassification = CustomerContent;
|
|
|
|
fields
|
|
{
|
|
field(1; "Primary Key"; Code[10]) { }
|
|
field(2; "Default Location Code"; Code[10]) { }
|
|
field(3; "Open Requests"; Integer) { }
|
|
}
|
|
|
|
keys
|
|
{
|
|
key(PK; "Primary Key") { Clustered = true; }
|
|
}
|
|
}
|
|
|
|
codeunit 50101 "Transfer Request Count Good"
|
|
{
|
|
[EventSubscriber(ObjectType::Table, Database::"Transfer Request Good", OnAfterInsertEvent, '', false, false)]
|
|
local procedure CountOpenRequest(var Rec: Record "Transfer Request Good"; RunTrigger: Boolean)
|
|
var
|
|
TransferSetup: Record "Transfer Setup Good";
|
|
begin
|
|
// Serializes the read-modify-write so concurrent background sessions don't lose an increment.
|
|
TransferSetup.LockTable();
|
|
TransferSetup.Get();
|
|
TransferSetup."Open Requests" += 1;
|
|
TransferSetup.Modify();
|
|
end;
|
|
}
|