Dynamics 365 Business Central: การใช้งาน Isolated Event ใน AL Programming

ในภาษา AL ที่ใช้สำหรับการพัฒนา Extension ใน Microsoft Dynamics 365 Business Central มีความสามารถใหม่ที่เรียกว่า Isolated Events ซึ่งช่วยให้การจัดการกับข้อผิดพลาด (Error Handling) ใน Event Subscriber มีประสิทธิภาพมากขึ้น บทความนี้จะอธิบายรายละเอียดเกี่ยวกับ Isolated Events พร้อมตัวอย่างการใช้งาน และแสดงวิธีการประกาศ Procedure ที่เกี่ยวข้อง

Isolated Events คืออะไร?

Isolated Events เป็นคุณสมบัติที่ช่วยให้ Event Subscribers สามารถทำงานอย่างเป็นอิสระ (Isolated) จากกัน เมื่อเกิดข้อผิดพลาดใน Subscriber หนึ่ง จะไม่ส่งผลกระทบต่อการทำงานของ Subscribers อื่นๆ หรือการทำงานของโปรแกรมหลัก (Main Code)

ทำไมต้องใช้ Isolated Events?

  • ความเสถียรของระบบ: เมื่อมีข้อผิดพลาดเกิดขึ้นใน Subscriber หนึ่ง โปรแกรมหลักยังคงทำงานต่อไปได้
  • การควบคุมข้อผิดพลาด: ช่วยให้สามารถจัดการกับข้อผิดพลาดในระดับของ Subscriber ได้โดยไม่กระทบกับการทำงานอื่น
  • การย้อนกลับการเปลี่ยนแปลง: ถ้า Subscriber ทำการเปลี่ยนแปลงข้อมูลในฐานข้อมูลและเกิดข้อผิดพลาด การเปลี่ยนแปลงนั้นจะถูกยกเลิก (Rolled Back)

การประกาศ Isolated Events

การประกาศ Isolated Event ใน AL ทำได้โดยการใช้ Attribute [InternalEvent(false, true)] โดยมีรูปแบบดังนี้

[InternalEvent(false, true)]
local procedure MyIsolatedEvent(Parameters)
begin
    // Event Logic
end;
  • IncludeSender (พารามิเตอร์ตัวแรก)
  • Isolated (พารามิเตอร์ตัวที่สอง, Optional)

ตัวอย่างการใช้งาน Isolated Events

codeunit 50100 SimpleIsolatedEventSample
{
    trigger OnRun()
    var
        MessageText: Text[100];
    begin
        MessageText := 'เริ่มต้น';

        MyIsolatedEvent(MessageText);

        Message('ข้อความสุดท้าย: %1', MessageText);
    end;

    [InternalEvent(false, true)]
    local procedure MyIsolatedEvent(var MessageText: Text[100])
    begin
        // เหตุการณ์นี้จะมีผู้ติดตามเหตุการณ์สองตัว
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::SimpleIsolatedEventSample, 'MyIsolatedEvent', '', false, false)]
    local procedure FailingSubscriber(var MessageText: Text[100])
    begin
        MessageText := MessageText + ' | จาก FailingSubscriber';
        Error('เกิดข้อผิดพลาดใน FailingSubscriber');
        // โค้ดด้านล่างนี้จะไม่ถูกเรียกใช้เนื่องจากเกิดข้อผิดพลาด
        MessageText := MessageText + ' | หลังจากข้อผิดพลาด';
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::SimpleIsolatedEventSample, 'MyIsolatedEvent', '', false, false)]
    local procedure SuccessfulSubscriber(var MessageText: Text[100])
    begin
        MessageText := MessageText + ' | จาก SuccessfulSubscriber';
    end;
}

การอธิบาย Source Code

1. ส่วนของ OnRun()

trigger OnRun()
var
    MessageText: Text[100];
begin
    MessageText := 'เริ่มต้น';

    MyIsolatedEvent(MessageText);

    Message('ข้อความสุดท้าย: %1', MessageText);
end;
  • กำหนดค่าเริ่มต้นให้กับ MessageText เป็น 'เริ่มต้น'
  • เรียกใช้ MyIsolatedEvent(MessageText); ซึ่งเป็น Isolated Event
  • แสดงผลข้อความสุดท้ายของ MessageText ด้วย Message()

2. การประกาศ Isolated Event MyIsolatedEvent

[InternalEvent(false, true)]
local procedure MyIsolatedEvent(var MessageText: Text[100])
begin
    // เหตุการณ์นี้จะมีผู้ติดตามเหตุการณ์สองตัว
end;
  • ใช้ Attribute [InternalEvent(false, true)] เพื่อกำหนดให้เป็น Isolated Event
  • รับ Parameter เป็น var MessageText: Text[100] เพื่อให้ Subscribers สามารถแก้ไขค่าได้

3. Subscriber ที่เกิดข้อผิดพลาด FailingSubscriber

[EventSubscriber(ObjectType::Codeunit, Codeunit::SimpleIsolatedEventSample, 'MyIsolatedEvent', '', false, false)]
local procedure FailingSubscriber(var MessageText: Text[100])
begin
    MessageText := MessageText + ' | จาก FailingSubscriber';
    Error('เกิดข้อผิดพลาดใน FailingSubscriber');
    // โค้ดด้านล่างนี้จะไม่ถูกเรียกใช้เนื่องจากเกิดข้อผิดพลาด
    MessageText := MessageText + ' | หลังจากข้อผิดพลาด';
end;
  • เพิ่มข้อความ ' | จาก FailingSubscriber' ต่อท้าย MessageText
  • ทำให้เกิดข้อผิดพลาดด้วย Error('เกิดข้อผิดพลาดใน FailingSubscriber');
  • โค้ดหลังจาก Error() จะไม่ถูกดำเนินการ

4. Subscriber ที่ทำงานสำเร็จ SuccessfulSubscriber

[EventSubscriber(ObjectType::Codeunit, Codeunit::SimpleIsolatedEventSample, 'MyIsolatedEvent', '', false, false)]
local procedure SuccessfulSubscriber(var MessageText: Text[100])
begin
    MessageText := MessageText + ' | จาก SuccessfulSubscriber';
end;
  • เพิ่มข้อความ ' | จาก SuccessfulSubscriber' ต่อท้าย MessageText

การทำงานของโปรแกรม

1. เมื่อ OnRun() ถูกเรียกใช้ MessageText จะถูกตั้งค่าเป็น 'เริ่มต้น'
2. เรียกใช้ MyIsolatedEvent(MessageText); ซึ่งมี Subscribers สองตัว
3. การเรียกใช้ Subscribers:
- FailingSubscriber:
- เพิ่มข้อความ ' | จาก FailingSubscriber' ใน MessageText
- ทำให้เกิดข้อผิดพลาดด้วย Error()
- การเปลี่ยนแปลงใน MessageText จะยังคงอยู่
- SuccessfulSubscriber:
- เพิ่มข้อความ ' | จาก SuccessfulSubscriber' ใน MessageText
4. กลับมาที่ OnRun() และแสดงผล MessageText

ผลลัพธ์ที่แสดง

ข้อความสุดท้าย: เริ่มต้น | จาก FailingSubscriber | จาก SuccessfulSubscriber

การวิเคราะห์

  • Isolated Event ช่วยให้ข้อผิดพลาดใน FailingSubscriber ไม่หยุดการทำงานของโปรแกรมหลัก
  • การเปลี่ยนแปลงในตัวแปร MessageText ภายใน Subscribers จะยังคงอยู่ แม้ว่าเกิดข้อผิดพลาด
  • Subscribers ที่เหลือ (SuccessfulSubscriber) ยังคงถูกเรียกใช้ตามปกติ

การจัดการกับการเปลี่ยนแปลงในฐานข้อมูล

หากมีการเปลี่ยนแปลงฐานข้อมูลใน Subscriber ที่เกิดข้อผิดพลาด การเปลี่ยนแปลงนั้นจะถูกยกเลิก

ตัวอย่างเพิ่มเติม

[EventSubscriber(ObjectType::Codeunit, Codeunit::SimpleIsolatedEventSample, 'MyIsolatedEvent', '', false, false)]
local procedure DatabaseChangingSubscriber()
var
    Customer: Record Customer;
begin
    Customer.DeleteAll(); // พยายามลบข้อมูลลูกค้าทั้งหมด
    Error('เกิดข้อผิดพลาดหลังจากลบลูกค้า');
end;
  • เมื่อเกิดข้อผิดพลาด การลบข้อมูลในตาราง Customer จะถูกยกเลิก
  • ข้อมูลในฐานข้อมูลจะไม่ถูกเปลี่ยนแปลง

สรุป

  • Isolated Events ช่วยให้การจัดการข้อผิดพลาดใน Event Subscribers มีประสิทธิภาพมากขึ้น
  • ข้อผิดพลาดใน Subscriber จะไม่หยุดการทำงานของโปรแกรมหลักหรือ Subscribers อื่น
  • การเปลี่ยนแปลงในตัวแปรภายใน Subscribers จะยังคงอยู่ แม้ว่าเกิดข้อผิดพลาด
  • การเปลี่ยนแปลงในฐานข้อมูลจะถูกยกเลิกหาก Subscriber นั้นเกิดข้อผิดพลาด
  • การประกาศ Isolated Event ใช้ [InternalEvent(false, true)]

ข้อควรระวังและคำแนะนำ

  • ควรใช้ Isolated Events เมื่อจำเป็นต้องให้โปรแกรมหลักทำงานต่อเนื่อง แม้ว่าจะมีข้อผิดพลาดใน Subscribers
  • การจัดการข้อผิดพลาดใน Subscribers ควรทำอย่างรอบคอบ เพื่อป้องกันผลกระทบที่ไม่คาดคิด
  • ควรตรวจสอบและทดสอบการทำงานของ Subscribers อย่างละเอียด

Leave a comment