یکی دیگر از گروه های مهم سیستم های توزیعی در سازمان هایی مشاهده میشود که گرچه با مجموعه ای از برنامه های کاربردی شبکه شده سر و کار دارند، اما قابلیت کار با هم برای آنها تجربه ای بسیار سخت است.

سیستم های اطلاعات توزیعی

 

بسیاری از راه حل های میان افزاری موجود، نتیجه کار با زیرساخت هایی است که در آنها ادغام برنامه های کاربردی در یک سیستم اطلاعاتی شرکتی آسان تر بوده است.

 

یکپارچگی در سطوح مختلفی قابل تشخیص است. در بسیاری از موارد، یک برنامه کاربردی شبکه شده فقط متشکل از خدمتگزار اجراکننده آن برنامه کاربردی (در اغلب موارد مجهز به یک پایگاه داده) بود که در اختیار برنامه های از راه دوری موسوم به مشتری یا کاربر (client) قرار میگرفت.

این مشتریان قادر به ارسال درخواست اجرای یک عملیات خاص برای خدمتگزار و متعاقب آن دریافت پاسخ بودند.

ادغام در پایین ترین لایه به کاربران اجازه میداد تا تعدادی از درخواست ها را، که گاهی اوقات برای خدمتگزارهای مختلف بودند، در قالب یک درخواست بزرگ بسته بندی کرده و تحت عنوان تراکنش توزیعی (Distributed Transaction) اجرا کند.

ایده اصلی آن بود که یا تمام درخواست ها اجرا شود و یا هیچ یک از آنها.

 

با پیشرفته تر شدن برنامه های کاربردی و تفکیک تدریجی آنها به مولفه های مستقل (خصوصاً تمایز بین مولفه های پایگاه داده از مولفه های پردازشی)، مشخص شد که بهتر است ادغام از طریق ایجاد امکان ارتباط مستقیم برنامه های کاربردی با یکدیگر نیز انجام گیرد.

این ویژگی اکنون منجر به صنعت عظیمی شده که روی ادغام برنامه کاربری شرکتی (Enterprise Application Integration – EAL) متمرکز شده است.

در ادامه توضیحات بیشتری راجع به این دو شکل از سیستم های توزیع شده ارائه خواهیم داد.

 

سیستم های پردازش تراکنش

برای روشن تر شدن بحث، روی برنامه های کاربردی پایگاه داده تمرکز میکینم.

در عمل، عملیات روی پایگاه داده معمولاً در قالب تراکنش (Transaction) انجام میشود.

برنامه نویسی با استفاده از تراکنش ها مستلزم آشنایی با عمل های پایه (Primitives) خاصی است که یا باید به وسیله سیستم های توزیعی زیربنایی تأمین شود و یا از طریق سیستم زمان اجرای زبان برنامه نویسی.

برخی از نمونه های عمل های پایه تراکنش در جدول زیر نشان داده شده است.

عمل پایهتوضیح
BEGIN_TRANSACTIONآغاز تراکنش را علامت گذاری میکند
END_TRANSACTIONپایان تراکنش را علامت گذاری میکند
ABORT_TRANSACTIONتراکنش را قطع کرده و مقادیر قبلی را برمیگرداند
READداده ها را از یک فایل، جدول و … میخواند
WRITEداده ها را در یک فایل، جدول و … مینویسد

 

لیست دقیق عمل های پایه بستگی به نوع اشیاء مورد استفاده در تراکنش دارد.

به عنوان مثال، در یک سیستم پستی، با عمل های ساده و پایه ای ارسال، دریافت و باز ارسال مواجه هستیم؛ اما در یک سیستم حسابداری ممکن است عمل های پایه ای کاملا متفاوتی به چشم بخورد.

اما عمل های READ و WRITE از نمونه های معروف و متداول در اغلب سیستم ها هستند. دستورات عادی، فراخوانی های روال و امثال آن هم در تراکنش ها مجاز هستند.

 

از BEGIN_TRANSACTION و END_TRANSACTION برای مشخص کردن محدوده تراکنش ها استفاده شده و عملیات بین آنها، بدنه تراکنش را تشکیل میدهند.

 

همانطور که در ادامه خواهیم گفت، فراخوانی روال راه دور (انگلیسی یا به اختصار RPC) هم غالباً به شکل تراکنش بسته بندی شده و چیزی به نام RPC تراکنشی (Transactional RPC) به وجود می آورد.

 

ویژگی بارز تراکنش آن است که یا تمام این عمل ها اجرا میشوند یا هیچ یک از آنها.

عملیات ممکن است بسته به نوع پیاده سازی، فراخوانی های سیستم، روال های کتابخانه ای یا بلوک هایی از دستورات برنامه نویسی باشند.

 

ویژگی گفته شده (همه یا هیچ) برای تراکنش ها، یکی از چهار ویژگی عمده تمام تراکنش هاست. به بیان دقیق تر، تراکنش ها دارای ویژگی های زیر هستند:

اولین ویژگی مهم تمامی تراکنش ها تقسیم ناپذیری (Atomic) است. بر اساس این ویژگی، تمامی تراکنش ها یا به طور کامل و البته طی یک اقدام فوری و تفکیک ناپذیر، انجام میشوند یا اصلا رخ نمیدهند.

در حین انجام فرآیند، فرآیند های دیگر (چه خود آنها در تراکنش ها شرکت داشته باشند و چه نه) قادر به مشاهده هیچ یک از وضعیت های میانی تراکنش نیستند.

 

دومین ویژگی سازگار بودن (Consistent) تراکنش است؛ به این معنی که سیستم دارای اصول بنیادی است که باید همواره برقرار باشند.

به عنوان مثال در سیستم های بانکداری، یکی از اصول مهم، قانون حفاظت از پول است. پس از هر نقل و انتقال داخلی، مقدار وجه موجود در بانک باید معادل مقدار آن پیش از انتقال باشد. اما در صورت مخدوش شدن این اصول در حین تراکنش، حتی به صورت لحظه ای، این اشکال از دید دنیای بیرون کاملاً مخفی خواهد ماند.

 

ویژگی سوم به این مسئله اشاره دارد که تراکنش ها ایزوله (Isolated) بوده یا سریال پذیر (Serializable) هستند. به این معنا که چنانچه دو یا چند تراکنش به صورت همزمان در حال انجام باشند، نتیجه نهایی برای هر یک از آنها و برای فرآیندهای دیگر، طوری است که گویی تمام تراکنش ها با ترتیبی مشخص (وابسته به سیستم) انجام شده اند.

 

ویژگی چهارم دوام (Durable) بوده و به این معناست که تراکنش ها در صورت تعهد اجرایی، بدون کوچکترین توجهی به رویدادها و اتفاقات جانبی به پیش رفته و نتایج آنها دائمی میشوند.

پس از انجام تعهد اجرایی، هیچ خرابی نمیتواند نتایج را ملغی کرده یا باعث مفقود شدن آنها شود.

 

در نتیجه صحبت های بالا، ویژگی تراکنش ها را میتوانیم به صورت زیر خلاصه کنیم:

1- تقسیم ناپذیری: از دید دنیای خارج، تراکنش به صورت یک کل تفکیک ناپذیر اجرا میشود.

2- سازگار بودن: تراکنش اصول بنیادی سیستم را مخدوش نمیکند.

3- ایزوله بودن: تراکنش های همزمان با یکدیگر تداخل ندارند.

4- دوام: تغییرات ناشی از تراکنش ها دائمی هستند.

 

گاهی اوقات این ویژگی ها با چسباندن حروف اول آنها در مجموع ACID خوانده میشوند.

 

تا به اینجا، تراکنش ها روی یک پایگاه داده منفرد تعریف شده است. مطابق تصویر زیر، تراکنش تو در تو (Nested Transaction) از تعدادی زیر تراکنش (SubTransaction) تشکیل میشود.

ممکن است در بالاترین سطح تراکنش با منشعب کردن فرزندانی که به صورت موازی با هم، اما روی ماشین های مختلف اجرا میشوند، باعث افزایش عملکرد یا تهسیل برنامه نویسی شود.

هر یک از این فرزندان هم ممکن است یک یا چند زیر تراکنش اجرا کرده و یا فرزندان خود را منشعب کنند.

تراکنش تو در تو

 

زیر تراکنش ها اشکالی کوچک اما مهم را مطرح میکنند. فرض کنید که یک تراکنش چندین زیر تراکنش را به صورت موازی با هم راه اندازی کرده و یکی از آنها را تعهد میکند؛ همین امر باعث قابل رؤیت شدن نتایج آن برای تراکنش مادر میشود.

با پیشروی محاسبات، مادر فرزند خود را قطع کرده (ABORT) و کل سیستم را به وضعیت پیش از آغاز تراکنش بالاترین لایه باز میگرداند.

بنابراین، نتایج زیر تراکنش تعهد شده بایستی ملغی شود. در نتیجه، مهفوم ماندگاری که در بالا گفته شد، فقط در مورد تراکنش های بالاترین لایه صدق میکند.

 

از آنجایی که تراکنش ها را میتوان به عمق دلخواه تو در تو کرد، برای انجام درست کارها نیازمند سرپرستی قابل ملاحظه ای هستیم. اما معانی مشخص هستند.

با آغاز هر تراکنش یا زیر تراکنش، از نظر مفهومی کپی اختصاصی از تمامی داده های موجود در کل سیستم در اختیار آن قرار داده میشود تا در صورت لزوم این داده ها را دستکاری کند.

در صورت قطع شدن، دنیای خصوص آن ناپدید میشود، گویی که اصلاً وجود نداشته است.

در صورت تعهد اجرایی، این دنیای خصوصی جایگزین دنیای مادر میشود. بنابراین، چنانچه یک زیر تراکنش تعهد اجرایی شده و سپس زیر تراکنش جدیدی آغاز شود، زیر تراکنش اخیر نتایج زیر تراکنش اول را مشاهده خواهد کرد.

به همین ترتیب، در صورت قطع شدن تراکنش (سطح بالاتر) دربرگیرنده  سایر تراکنش ها، تمامی زیر تراکنش های آن هم قطع خواهند شد.

 

تراکنش های تو در تو، از آنجایی که یک روش طبیعی برای توزیع تراکنش ها بین ماشین های مختلف به وجود می آورند، در سیستم های توزیعی دارای اهمیت هستند.

این تراکنش ها از تقسیم بندی منطقی عملیات تراکنش اصلی تبعیت میکنند.

مثلاً، تراکنش مربوط به طرح ریزی سفری که باید برای آن 3 پرواز مختلف رزرو شوند، را میتوان منطقاً به سه زیر تراکنش تقسیم کرد. هر یک از این زیر تراکنش ها به صورتی جداگانه (و مستقل از دو زیر تراکنش دیگر) قابل مدیریت هستند.

 

در اوایل ابداع سیستم های میان افزاری شرکتی، مؤلفه ای که کار تراکنش های توزیعی (یا تو در تو) را انجام میداد، در واقع هسته ادغام کنندۀ برنامه های کاربردی در سطح خدمتگزار یا پایگاه داده را تشکیل میداد.

این مولفه ناظر پردازش تراکنش (Transaction Processing Monitor) یا به طور خلاصه ناظر TP خوانده میشد.

وظیفه این مولفه ایجاد امکان دسترسی برنامه های کاربردی به پایگاه داده / خدمتگزاران متعدد از طریق ارائه یک مدل برنامه نویسی تراکنشی به آن بود.

در تصویر زیر، میتوانید نقش ناظر TP در سیستم های توزیعی را ببینید.

نقش ناظر TP در سیستم های توزیعی