ในภาษา 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 อย่างละเอียด
