ACID چیست؟


1.Atomicty

رک پوست کنده بگم یعنی یا تمام دستورات اجرا میشن یا نمیشن!

یکمش بشه ، نصفش بشه ، باباش نذاشت که اجرا بشه، رفت دید اندازش نیست و اینا نداریم.

یا همش یا هیچیش!

2.Consistency

در این بحث ما دوتا مورد داریم ، یکی Data Consistency یکی هم Read Consistency خب اینا یعنی چی؟؟؟؟

Data Consistency

شما نگا کنن این مورد رو خود کاربر تعیین میکنه مثلا در دیتا بیس های Relational ما از کلید های خارجی استفاده میکنیم که رو هوا داده وارد نشه!یکم منطق و دلیل پشتش باشه.

البته اگه بررسی کنید متوجه میشید که این بخش Atomicty بی ربط به اینجا نیست!چرا؟چون شما فکر کن یک پولی انتقال میدی، بعد دیتا بیس (حالا به هر دلیلی) کرش میکنه ! الله اکبر پوله کجا رفت ! اگه Atomicty نبود که رفت هوا ولی چون هست!برمیگرده سرجاش!حالا اگه شما نگاه کنین اگه نبود که Data Consistency خراب میشد!

حالا مثال ! فکر کن یک جدول داری که توش لایک ها رو مثلا همین لینکدین! ذخیره میکنی ! بعد میبینی که اگه لایک ها زیادبشه اون موقع معنی نمیده که بری توی جدول لایک هات کوئری بزنی تعداد بگیری! یک فیلد توی جدول پست ها اضافه می کنی که سیستم هر ازگاهی میره با صله رحم به جدول لایک پست ها یک کوئری میگیره و تعداد رو توی این فیلد میزاره!بعدا که خواستی میخونیش!چرا چون سریع تره!

حالا اگه پست بیانسه! موقع نمایش لایک هاش به جای 12503 لایک بگی که 12K لایک خورده ! زمین به اسمون میاد!؟ نه!پس همین کارو میکنی ! اما اگه برنامه موجودی حسابه و انتقال پول دیگه از این خبرا نیست و طراحیش سخت تره!

اصلا یک علتی هم که مردم میان Delete Cascade میزارن توی بانک ها همینه!شما فکر کن یک پستی حذف بشه! بعد رکورد هایی که لایک ها رو نگه میداشته، نشه!چی بشه! کی جمع کنه اون همه داده یتیم رو!

Read Consistency

این بحث خیلی بزرگه! ولی خب چون امروزه همه یاد گرفتن که برن سراغ میکروسرویس ها ( مونولوتیک دور نندازین، انقدر ها هم بدرد نخور نیست!)و بعدش بیان با یک CQRS به لطف کتابخانه های متعدد، Read رو بدن به این دیتابیس قشنگا مثل ردیس و Write و رو بدن به مثلا SQL Server حالا داستان اینه که در سیستم های خیلی خیلی بزرگ زمان میبره که ردیس بدبخت با این بانک اصلی هماهنگ بشه!این یکی از مسائلی قابل مثال برای Read Consistency هستش! که یک بحث جالبی پیش اومده به اسم eventual Consistency که یعنی دیر و زود داره ولی سوخت سوز نداره! بالاخره اینا باهم هماهنگ میشن!( یک مطلب کامل برای همین خواهم نوشت!)

یعنی بالاخره آقا در سیستم های خیلی بزرگ گاهی پیش میاد که ما داده ای رو ذخیره کنیم و زمانی طول بکشه هرچند کوتاه) این داده هماهنگ بشن!

خب!

3.Isolation

اگه یک Transaction اجرا بشه چهار اتفاق میتونه بی افته

1- داده بخونی که امکان داره اصلا کامیت نشده باشه!یا ابالفضل!(Dirty Read)

2- داده بخونی! کامیت باشه ها!اما توی لیست رکورد های خروجی نباشه!دوباره مجبوری کوئری بگیری(non-repeatable Read)
مثال بزنم ! فکر کن داری جمع خرید های امروز رو میگیری به همراه لیستشون و قبل اینکه برسی به دستور SELECT آخر که مال خروجی گرفتن هستش، یک بنی بشری میاد تعداد خرید هارو آپدیت میکنه(مثلا دستی توسط صندوق دار) شما 12 تا آیتم داری که دستی حساب میکنی جمعش میشه 1200 تومن ، بعد اومدی SUM که توی دیتابیس گرفتی رو نگاه میکنی میبینی نوشته 1000 تومن یعنی چی؟ یعنی دارای non-repeatable Read شدی ! مجبوری دوباره گزارش بگیری.

3- قبلیه با یک لاک کردن ردیف یا ستون یا جدول یا... قابل حل هستش ! نمیزاری که آپدیت کنن!ولی اگه یکی جدید اضافه کردن چی؟جمع دستی کالا ها که تعدادش 12 تا هستش شده 1200 تومن ولی جمع سیستمی میگه 1400 تومن! اون یکی کو؟؟؟؟اضافه شده ولی توی لیست نیست!(phantom Read)

4- شما فکر کن یک ردیفی رو میخوای اپدیت کنی!و transaction رو اجرا میکنی!هم زمان یک بنی بشر دیگه ای هم داره روی همون داده همین کارو میکنه!شما دکمه ذخیره رو میزنی میبینی یک چیز دیگه آپدیت شده!(یا بالعکس) به این مسئله میگن (lost Update)

برای روضه هایی که بالا خوندم اومدن راه هایی در نظر گرفتن که این بسته به حساسیت داده به روش های مختلف جبران میشه!

1-Read uncommitted یعنی آقا هیچ کاری نکن اصلا اگه حتی داده کامیت نشده بود هم بخون!(تمام تراکنش ها از هم خبر دارن و روی هم تاثیر میزارن حتی اونایی که امکان داره وسط راه Roleback بشن!و شماDirty Read رو داری! )

2-Read Commited تراکنش ها فقط تغییرات کامیت شده رو میبینن! Dirty Readحل شده اینجا!

3-Repeatable Read اینجا دیتابیس مطمئن میشه که وسط راه کسی به دیتا کُخ نریزه(مشهدی هستش یعنی تغییر نده) حالا چجوری مثلا با لاک کردن داده(خودش یک درس سه واحدیه!)

4-SnapShot یعنی شما فکر کن در زمان شروع تراکنش یکی عکس از دیتابیس میگیره و با همون داده ها کار میکنه!مشکل ها همه حل میشه!

5-Serializable این دیگه معرکس! اصلا همزمانی وجود نداره! همه تراکنش ها پشت سر هم اجرا میشن!اینجا هم حل میشه!

حالا این داستان هارو هر دیتابیسی یک جور کنترل میکنه!اره خلاصه!

مثال Postgres میاد Repeatable Read رو مثل snapshot هندل میکنه!

حالا این یعنی چی؟؟یعنی اگه من یک داده ای رو ذخیره کردم و سیستم رو خاموش کردم، بعدش که اومدم سراغش بهتره سرجاش باشه ! همه دیتابیس ها این کار نمیکنن مثلا ردیس(البته می کنه ها شما باید براش تنظیم کنی) این خودشم سه روش داره که باشه بعدا یکی یکی مطلب میزارم براش!