فرض کنیم یه اپلیکیشن بانکی میخایم بنویسیم که حسابهای افراد رو مدیریت کنه. برای این کار یک روش اینه که اگه طرف مثلا 1 میلیون بریزه توی حسابش اپلیکیشن بره و مقداره متغیر مانده حساب رو با 1 میلیون اضافه کنه. و هر وقت x تومن خرج میکنه این متغیر رو x واحد کم کنه. این چه مشکلی میتونه داشته باشه:
1.ممکنه race condition پیش بیاد و چند تا thread یا پروسه مقدار رو با هم تغییر بدن و در این حالت عملا حساب بانکی مشتری رو خراب کردیم
2.تاریخچه ای از تراکنش ها وجود نداره که بتونیم پرینت حساب بگیریم
بهترین روش اینه که مقدار حساب مشتری یه متغیر غیرقابل تغییر باشه 🙂 “فکر نکنم دیگه بشه بهش گفت متغیر” و تراکنش ها رو ذخیره کنیم مثلا مقدار 1 میلیون هست و وقتی x تومن خرج میکنه دیگه از اون مقدار کم نکنیم و فقط یه تراکنش -x ثبت کنیم. در این حالت دیگه حساب مشتری خراب نمیشه. تاریخچه حساب معلومه و race condition به وجود نمیاد. این روشی هست که توی اپلیکیشن های بانکی ازش استفاده میشه و بهش میگن Event Sourcing.
مشکل این روش اینه که فرض کنیم مشتری توی یک ماه گذشته به تعداد 200 هزار تراکنش داشته و الان مانده حساب میگیره. اپلیکیشن باید 200 هزار تراکنش رو باهم جمع کنه و اپلیکیشن کند میشه. برای این مشکل کافیه آخر هر شب تراکنش ها با هم جمع شن و مانده حساب نصف شب محاسبه بشه. بنابراین در هر روز فقط تراکنش ها اون روز برای محاسبه مانده حساب مهمه.
مشکل دوم اینه که دیسک زیادی نیاز هست چون باید تمامی تراکنش های تمامی کاربران نگهداری شه.
اگر منابعی مثل CPU و Disk به اندازه کافی داشته باشیم میتونیم تمامی متغیرها رو immutable کنیم و بنابراین برنامه کاملا Functional باشه. در این حالت البته توسعه سخت تر هم هست.