Domain Driven Design - بخش چهارم

در این بخش، مفهوم Consistency را بررسی می کنیم.Domain Driven Designوقتی در مورد Consistency صحبت می کنیم، منظور یکپارچگی و valid بودن داده ها است. در نوع Atomic Consistency یا Transactional Consistency، در نظر بگیرید که دو داده داریم و عملیات consistent را بصورت atomic یا transactional بر روی آن ها انجام می دهیم. برای مثال، زمانی که می خواهیم از حسابی پول کم کنیم و در حساب دیگر بریزیم. در این مساله کم شدن و اضافه شدن مبلغ در یک لحظه انجام شود. یک نوع consistency دیگر به نام Eventual Consistency وجود دارد. در این نوع، ممکن است لحظاتی در سیستم وجود داشته باشد که در مثال قبل، پول از حساب کم شده باشد و به حساب دیگری ریخته نشده باشد. اما در نهایت consistency در سیستم اتفاق می افتد. دو نگاه متفاوت به consistency وجود دارد. نگاه اول از نوع ACID یا Atomic Consistent Isolated Durable است و نگاه دوم از نوع BASE یا Basic Availability Soft-state Eventual consistency می باشد که به دو موضوع متفاوت اشاره می کنند. در قاعده ای که به عنوان CAP یا Consistency Availability Partition tolerance وجود دارد، اگر سه موضوع consistence بودن داده ها، در دسترس بودن سیستم و تحمل سیستم به partition شدن را در نظر بگیریم، در لحظه فقط دو مورد از این سه موضوع را می تونیم داشته باشیم. در نظر بگیرید که یک دیتابیس را به سه node مختلف partition کرده ایم. در لحظه t1 یک نفر در partition اول داده ای را می نویسد. در لحظه t2 یه نفر از partition دوم داده را می خواند. اگر سیستم را منتظر بگذاریم تا تمام nodeها sync شوند، در نتیجه availability را کنار گذاشتیم و consistency و partition tolerance را انتخاب کرده ایم. اگر سیستم، داده ای که وجود دارد را همان لحظه برگرداند، در نتیجه consistency را کنار گذاشتیم و availability و partition tolerance را انتخاب کرده ایم. و اگر تحمل سیستم به partition شدن را کنار بگذاریم، consistency و availability را انتخاب کرده ایم. دیتابیس های NoSQL، عمدتا به مدل Base کار می کنند. به این دلیل که امکان transaction بین چند document را به ما نمی دهند. این دیتابیس ها با تفکر طراحی aggregate سازگاری دارند. قانونی که در tactical modeling وجود دارد، اشاره به این موضوع دارد که درون یک aggregate، خاصیت transactional consistency را می بینیم و بیرون از یک aggregate، خاصیت eventually consistency را می بینیم. برای مثال، یک BC به نام Auction یا حراجی داریم که در آن کالایی معرفی می شود و قیمت شروع نیز مشخص می شود. افراد می توانند پیشنهادهای مختلفی را روی آن بزنند تا در نهایت بالاترین قیمت برنده شود. invariantهایی که در این مساله وجود دارد، قیمت شروع باید بزرگتر از صفر باشد. پیشنهاد اول باید بیشتر از قیمت شروع باشد. پیشنهادهای بعدی باید از آخرین پیشنهاد بیشتر باشند. و ثبت پیشنهاد بر روی auctionهایی انجام می شود که در وضعیت باز باشند. بنابراین موجودیت هایی که در این سیستم وجود دارند شامل Auction یا حراج، Bid به عنوان تاریخچه پیشنهادها، Winning Bid به عنوان پیشنهاد برنده، Seller به عنوان فروشنده، Bidder یا پیشنهاد دهنده و Product می باشد.اگر Auction و Winning Bid را در یک aggregate قرار دهیم، می تونیم تمام invariantهای مساله را پاسخ دهیم.به موضوع transaction consistency فکر کنیم. در نظر بگیرید که یک command به نام PlaceBid به منظور ثبت پیشنهاد، در سیستم خود داریم. در گام اول Auction را load می کنیم، بعد از آن یک پیشنهاد به عنوان winning bid روی آن قرار می دهیم و در نهایت آن ذخیره می کنیم. فرض کنید بعد از انجام ذخیره، یک event به شکل async ارسال می شود و پیشنهاد جدید به عنوان تاریخچه در Bid ذخیره می شود. این عملیات را eventually consistency در نظر بگیرید. بنابراین Bid را هیچ وقت از سمت کاربر ثبت نمی کنیم و از طریق auction aggregate این کار انجام می شود. در نتیجه invariant آن از سمت auction بررسی می شود. موضوعی که وجود دارد، وجود گپ زمانی بین ذخیره پیشنهاد جدید و تاریخچه آن است. به این موضوع فکر کنیم که آیا وجود این گپ، business ما را دچار مشکل می کند یا خیر؟ از آنجایی که Auction و WinningBid در یک aggregate هستند و موضوعی که برای کاربر مهم است، آخرین پیشنهاد روی auction است، بنابراین بروز نبودن تاریخچه پیشنهادها، مشکلی را بوجود نمی آورد.در بسیاری از اوقات، موضوع eventually consistency از طریق روش های ساده ای، قابل حل شدن است. برای مثال نوشتن یک پیام مبنی بر زمان آخرین بروز رسانی می تواند یک راه حل باشد.