การตรวจสอบความสอดคล้องของธุรกรรมด้วย DDD


9

ฉันเริ่มต้นด้วย DDD และเข้าใจว่ามีการใช้รากรวมเพื่อรับรองความมั่นคงข้ามชาติ เราไม่ควรแก้ไขการรวมหลายรายการในบริการแอปพลิเคชันเดียว

ฉันต้องการทราบวิธีจัดการกับสถานการณ์ต่อไปนี้

ฉันมีรูทรวมที่เรียกว่าผลิตภัณฑ์

นอกจากนี้ยังมีรูทรวมที่เรียกว่ากลุ่ม

ทั้งสองมีรหัสและสามารถแก้ไขได้อย่างอิสระ

ผลิตภัณฑ์หลายรายการสามารถชี้ไปที่กลุ่มเดียวกัน

ฉันมีบริการแอปพลิเคชันที่สามารถเปลี่ยนกลุ่มของผลิตภัณฑ์:

ProductService.ChangeProductGroup(string productId, string groupId)

  1. ตรวจสอบกลุ่มที่มีอยู่
  2. รับผลิตภัณฑ์จากพื้นที่เก็บข้อมูล
  3. ตั้งค่ากลุ่ม
  4. เขียนผลิตภัณฑ์กลับไปที่ที่เก็บ

ฉันยังมีบริการแอปพลิเคชันที่สามารถลบกลุ่มได้:

GroupService.DeleteGroup(string groupId) 1. รับผลิตภัณฑ์จากที่เก็บซึ่ง groupId ถูกตั้งค่าเป็น groupId ที่ระบุตรวจสอบให้แน่ใจว่าการนับเป็น 0 หรือยกเลิก 2. ลบกลุ่มจากที่เก็บกลุ่ม 3. บันทึกการเปลี่ยนแปลง

คำถามของฉันคือสถานการณ์ต่อไปนี้จะเกิดอะไรขึ้นถ้า:

ใน ProductService.ChangeProductGroup เราจะตรวจสอบกลุ่มที่มีอยู่ (เช่นนั้น) จากนั้นหลังจากการตรวจสอบนี้ผู้ใช้ที่แยกต่างหากจะลบ productGroup (ผ่าน GroupService.DeleteGroup อื่น) ในกรณีนี้เราตั้งค่าการอ้างอิงถึงผลิตภัณฑ์ที่เพิ่งถูกลบ?

นี่เป็นข้อบกพร่องในการออกแบบของฉันที่ฉันควรใช้การออกแบบโดเมนที่แตกต่างกัน (เพิ่มองค์ประกอบเพิ่มเติมถ้าจำเป็น) หรือฉันจะต้องใช้การทำธุรกรรม?

คำตอบ:


2

เรามีปัญหาเดียวกัน

และฉันไม่เห็นวิธีที่จะแก้ปัญหานี้ แต่ด้วยธุรกรรมหรือด้วยการตรวจสอบความสอดคล้องที่ฐานข้อมูลเพื่อรับข้อยกเว้นในกรณีที่เลวร้ายที่สุด

คุณยังสามารถใช้การล็อคในแง่ร้ายบล็อกรูทรวมหรือเพียงบางส่วนของมันสำหรับลูกค้ารายอื่น ๆ จนกว่าการทำธุรกรรมทางธุรกิจจะเสร็จสมบูรณ์ในระดับที่เทียบเท่ากับการทำธุรกรรมแบบอนุกรม

วิธีที่คุณดำเนินการอย่างหนักนั้นขึ้นอยู่กับระบบและตรรกะทางธุรกิจของคุณ
การเห็นพ้องต้องกันไม่ใช่เรื่องง่ายเลย
แม้ว่าคุณสามารถตรวจพบปัญหาคุณจะแก้ไขได้อย่างไร? เพียงยกเลิกการดำเนินการหรืออนุญาตให้ผู้ใช้ทำการเปลี่ยนแปลง 'ผสาน'

เราใช้ Entity Framework และ EF6 ใช้ read_commited_snapshot ตามค่าเริ่มต้นดังนั้นการอ่านสองครั้งติดต่อกันจากที่เก็บสามารถให้ข้อมูลที่ไม่สอดคล้องกัน เราเพียงจำไว้ว่าในอนาคตเมื่อกระบวนการทางธุรกิจจะมีการระบุไว้อย่างชัดเจนมากขึ้นและเราสามารถตัดสินใจ infromed และใช่เรายังตรวจสอบความสอดคล้องในระดับแบบจำลองเช่นเดียวกับคุณ อย่างน้อยก็ให้ทดสอบ BL แยกต่างหากจากฐานข้อมูล

ฉันขอแนะนำให้คุณคำนึงถึงความสอดคล้องของที่เก็บในกรณีที่คุณมีธุรกรรมทางธุรกิจที่ 'ยาว' มันค่อนข้างยุ่งยากเมื่อปรากฏออกมา


1

ฉันคิดว่านี่ไม่ใช่คำถามเฉพาะการออกแบบที่ขับเคลื่อนด้วยโดเมน แต่เป็นการจัดการทรัพยากร

ทรัพยากรก็จะต้องมีการล็อคที่พวกเขาจะได้รับ

สิ่งนี้เป็นจริงเมื่อบริการแอปพลิเคชันรู้ล่วงหน้าว่าทรัพยากรที่ได้รับ (ตัวอย่างGroupรวมของคุณ) จะได้รับการแก้ไข ในการออกแบบที่ขับเคลื่อนด้วยโดเมนการล็อกทรัพยากรเป็นส่วนที่เป็นของที่เก็บ


ไม่การล็อคไม่ใช่ "ต้อง" ในความเป็นจริงมันเป็นสิ่งที่น่ากลัวเกี่ยวกับการทำธุรกรรมที่ยาวนาน คุณควรใช้การเห็นพ้องด้วยแง่ดีซึ่ง ORM สมัยใหม่ทุกอันรองรับการใช้งานได้ทันที และสิ่งที่ยอดเยี่ยมเกี่ยวกับการเห็นพ้องในแง่ดีคือมันยังทำงานได้กับฐานข้อมูลที่ไม่ทำธุรกรรมตราบใดที่พวกเขาสนับสนุนการปรับปรุงอะตอม
Aaronaught

1
ฉันเห็นด้วยกับข้อเสียของการล็อคในการทำธุรกรรมที่ใช้เวลานาน แต่สถานการณ์ที่อธิบายโดย @ g18c นั้นมีนัยสำคัญในทางตรงกันข้าม
rucamzu

0

ทำไมคุณไม่เก็บรหัสผลิตภัณฑ์ในเอนทิตีของกลุ่ม? วิธีนี้คุณจะจัดการกับการรวมกลุ่มเดียวซึ่งจะทำให้สิ่งต่าง ๆ ง่ายขึ้น

จากนั้นคุณจะต้องใช้รูปแบบการทำงานพร้อมกันบางประเภทเช่นหากคุณเลือกการทำงานพร้อมกันในแง่ดีเพียงเพิ่มคุณสมบัติของรุ่นไปยังเอนทิตีของกลุ่มและส่งข้อยกเว้นหากเวอร์ชันไม่ตรงกันเมื่ออัปเดตเช่น

เพิ่มผลิตภัณฑ์ในกลุ่ม

  1. ตรวจสอบว่ามีสินค้าอยู่หรือไม่
  2. รับ Group จากพื้นที่เก็บข้อมูล (รวมถึงคุณสมบัติ version id)
  3. Group.Add (productID)
  4. บันทึกกลุ่มโดยใช้ที่เก็บ (อัปเดตด้วย id เวอร์ชันใหม่และเพิ่มส่วนคำสั่งเพื่อให้แน่ใจว่าเวอร์ชันจะไม่เปลี่ยนแปลง)

ORM จำนวนมากมีการทำงานพร้อมกันในแง่ดีซึ่งสร้างขึ้นโดยใช้รหัสเวอร์ชันหรือการประทับเวลา แต่มันง่ายที่จะม้วนของคุณเอง นี่คือการโพสต์ที่ดีในการทำใน Nhibernate http://ayende.com/blog/3946/nhibernate-mapping-concurrency


0

แม้ว่าธุรกรรมอาจช่วยได้ แต่ก็มีวิธีอื่นโดยเฉพาะอย่างยิ่งหากสถานการณ์ของคุณถูก จำกัด เพียงไม่กี่กรณี

คุณสามารถรวมการตรวจสอบในแบบสอบถามที่ทำการกลายพันธุ์ทำให้การตรวจสอบและการกลายพันธุ์แต่ละคู่เป็นการดำเนินการของอะตอม

แบบสอบถามภายในอัพเดตผลิตภัณฑ์เข้าร่วมกลุ่ม (อ้างอิงใหม่) สิ่งนี้ทำให้ไม่มีการอัพเดทหากกลุ่มนั้นหายไป

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

แบบสอบถามส่งคืนจำนวนแถวที่จับคู่หรืออัปเดต หากผลลัพธ์เป็น 0 แสดงว่าคุณสูญเสียสภาพการแข่งขันและไม่ได้ทำอะไรเลย มันสามารถโยนข้อยกเว้นและเลเยอร์ของแอปพลิเคชันสามารถจัดการกับมันได้อย่างไรก็ตามมันต้องการเช่นโดยการลองอีกครั้งตั้งแต่เริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.