مشخصات مقاله
-
2065
-
0.0
-
5512
-
0
-
0
درس بیست و یک : آموزش مدیریت تراکنش ها در Spring
آموزش مدیریت تراکنش ها در Spring
یک تراکنش در پایگاه داده ( database transaction ) مجموعه ای از عملیات های داده ای متوالی ، است که بایستی به عنوان یک واحد کاری رفتار کند .
این مجموعه عملیات ها یا بایستی به صورت کامل با هم انجام شوند و یا اینکه کلا اثری برسیستم نداشته باشند . به عبارت دیگر تراکنش یا باید به طور کامل و موفقیت آمیز انجام شده و یا در کل لغو گردد .
مدیریت تراکنش ها ( transaction management ) بخش مهمی از سیستم مدیریت یکپارچه پایگاه های داده ( RDBMS ) بوده که درستی و ثبات ثبت و انتقال داده را کنترل می کند . مفهوم اساسی تراکنش های پایگاه داده را در چهار اصل کلیدی زیر می توان خلاصه است که به اختصار ACID نامیده می شوند :
- - Atomicity : یک تراکنش بایستی به عنوان یک موجودیت واحد از عملیات های متوالی و مرتبط در نظر گرفته شده و رفتار کند . کلید مراحل یک تراکنش بایستی یا به صورت کامل و موفقیت آمیز انجام شوند یا به کلی لغو گردند .
- - Consistency : این مفهوم به معنای حفظ یکپارچگی اطلاعات در پایگاه داده و اطمینان از ارتباط صحیح فیلدها و کلیدها در جدول ها است . از پارامترهای مهم این مفهوم به کلید خارجی ( foreign key ) یا کلید اصلی ( primary key ) می توان اشاره کرد .
- - Isolstion : در پروسه پردازش تراکنش های پایگاه داده ، ممکن است در زمان واحد تعدادی از تراکنش ها دارای Data Set مشترک باشند . بنابراین بایستی هر تراکنش از سایر تراکنش ها ایزوله شده تا از تداخل داده ها جلوگیری شود .
- - Durability : به محض اینکه یک تراکنش در پایگاه داده تکمیل شد بایستی نتیجه آن به صورت دائمی ثبت شده و قابل پاک کردن نباشد . زیرا عدم انجام این کار ، خطر از دست رفتن اطلاعات را به وجود می آورد .
یک سیستم واقعی و اصولی مدیریت یکپارچه پایگاه داده ( RDBNS ) بایستی اجرای هر چهار عمل فوق را ضمانت کند . ساده ترین رویه برای اجرا و تکمیل یک تراکنش به وسیله SQL در پایگاه داده به صورت زیر است :
- - آغاز اجرای تراکنش به وسیله دستور begin transaction .
- - انجام عملیات های مختلف حذف ، ویرایش ( Update ) ، وارد نمودن اطلاعات ( insert ) و ... به وسیله SQL queries .
- - اگر کلید عملیات های مورد نظر با موفقیت انجام شد بایستی دستور Commit ( ثبت نهایی ) انجام شده یا کل عملیات کسل ( rollback ) شود .
چهارچوب کاری Spring یک لایه مجزا را برروی API های مرتبط با مدیریت تراکنش ها ، جهت کنترل بهتر برنامه فراهم می کند . سیستم پشتیبانی تراکنش های Spring با هدف فراهم نمودن یک جایگزین برای تراکنش های EJB ایجاد شده که در آن قابلیت های مدیریت تراکنش ها را به POJO ها اضافه کرده است . Spring هر دو رویه برنامه نویسی و یا اعلان را برای مدیریت تراکنش ها ، پشتیبانی می کند . EJB برای انجام تراکنش ها به یک سرور نیازمند است ، اما مدیریت تراکنش های Spring می تواند بدون کمک از یک سرور ، کارهای خود را انجام دهد .
بررسی تراکنش های Global در مقابل Local :
تراکنش های محلی ( Local Transactions ) مختص منابع با معاملات تکی مثل JDBC می باشد . از طرف دیگر تراکنش های سراسری ( Global Transactions ) می تواند معاملات چند بعدی در منابع ای مثل سیستم های گسترده و چند کاربره را پوشش دهد .
مدیریت تراکنش محلی یا Local Transaction Managment در سیستم های کامپیوتری متمرکز که در آن کامپوزیت ها و منابع در یک سایت واحد هستند ، مفید است و Local Managment تراکنش های مختص یک پایگاه داده که برروی یک ماشین است را مدیریت می کند . تراکنش های محلی در اجرا بسیار ساده تر هستند .
از طرف دیگر ، مدیریت تراکنش های سراسری ( Global Transactions Management ) در سیستم های کامپیوتری گسترده که در آن کامپوزیت ها و منابع برروی سیستم های مختلف پخش شده اند ، لازم است . در چنین وضعیتی ، مدیریت تراکنش ها هم بایستی برروی کامپیوتر میزبان و هم بر روی سایر کامپیوترهای متصل به شبکه انجام شود .
یک تراکنش سراسری Global یا گسترده به صورت همزمان برروی چندین سیستم اجرا می شود . بنابراین اجرای این نوع تراکنش ها ، نیازمند هماهنگی بین سیستم مدیریت سراسری تراکنش ها و کلید سیستم های کلاینت موجود در سیستم می باشد .
کدنویسی Programmatic در مقابل Declarative :
Spring دو مدل مدیریت تراکنش ها را پشتیبانی می کند که عبارتند از :
- - Programmatic transaction management : در این روش ، مدیریت تراکنش ها به کمک برنامه نویسی انجام می شود . این روش قابلیت انعطاف پذیری زیادی به ما می دهد ، ولی از طرف دیگر برای طراحی کمی مشکل و زمان بر است .
- - Declarative transaction management : در این روش مدیریت تراکنش ها از لایه business برنامه جدا شده است . در این روش شما از annotations یا فایل های پیکربندی مبتنی بر XML برای مدیریت تراکنش ها بهره می گیرید .
Declarative transaction management نسبت به Programmatic transaction management بهتر است ، زیرا انعطاف پذیری کمتری داشته و به شما اجازه می دهد تا تراکنش های خود را توسط کد برنامه کنترل کنید .
اما به عنوان یک نوع از Crosscutting Concern ( تقسیم اجزای یک شی ) ، Declarative transaction management را می توان با استفاده از روش AOP به بخش های مختلف تقسیم کرد .
آموزش Spring Transaction Abstraction :
راهنمای لازم برای Spring Transaction Abstraction در رابط کاربری org.springframework.transaction.PlatformTransactionManager که کد آن در زیر نمایش داده شده تعیین شده است :
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition);
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
در جدول زیر به بررسی متدهای رابط کاربری فوق می پردازیم :
- متد TransactionStatus getTransaction(TransactionDefinition definition) : این متد تراکنش فعال جاری را بازگزدانده و یا یک تراکنش جدید را برحسب رفتار تعیین شده جهت برنامه ایجاد می کند .
- - متد Void Commit ( Transaction Status status ) : این متد ، تراکنش ارسال شده به آن را با توجه به وضعیت تراکنش ( statuts ) به برنامه می فرستد .
- - متد Void rollback ( TransactionStatus status ) : این متد ، عملیات انجام شده برروی تراکنش داده شده به آن را لغو ( rollerback ) میکند .
TransactionDefinition رابط کاربری مرکزی قابلیت پشتیبانی transaction در Spring بوده و با کدی همانند زیر تعیین می شود :
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
String getName();
int getTimeout();
boolean isReadOnly();
}
در جدول زیر به بررسی متدهای کد فوق و کاربرد آنها خواهیم پرداخت :
- - متد int getpropagation Behavior : این متد رفتار propagation را برمی گرداند . Spring کلید propagation های یک تراکنش را در راستای EJB CMT تعیین می کند .
- - متد int getIsolationLevel() : این متد درجه ای که در آن بایستی تراکنش مورد نظر از کار سایر تراکنش ها مجزا و ایزوله شود را برمی گرداند .
- - متد string getName() : این متد نام تراکنش مورد نظر را برمیگرداند .
- - متد intget Timeout() : این متد تعداد ثانیه هایی که طی آن ، تراکنش بایستی کامل شود را برمی گرداند .
- - متد Boolean isReadOnly() : این متد تعیین می کند آیا تراکنش جاری Read-only هست یا خیر .
- - مقدار TransactionDefinition.ISOLATION_DEFAULT : این خاصیت مقدار پیش فرض اول ایزوله شدن تراکنش است .
- - مقدار TransactionDefinition.ISOLATION_READ_COMMITTED : این مقدار تعیین می کند که خواندن تراکنش قبل از اجرای کامل ( dirty read ) امکانپذیر نیست . ولی خواندهای non-repeatable و Phontom read ممکن هستند .
- - مقدار TransactionDefinition.ISOLATION_READ_UNCOMMITTED : این مقدار تعیین میکند هر 3 حالت خواندن تراکنش در حالت dirty read ، non-reapeatable و Phontom read امکانپذیر است .
- - مقدار TransactionDefinition.ISOLATION_REPEATABLE_READ : این مقدار نیز تعیین می کند که فقط حالت خواندن Phntom read ممکن بوده و حالت های dirty read و non-reapeatable غیر ممکن است .
- - مقدار TransactionDefinition.ISOLATION_SERIALIZABLE : در این حالت کلیه حالت های مختلف خواندن تراکنش ممنوع است .
- حالت TransactionDefinition.PROPAGATION_MANDATORY : در این وضعیت تراکنش جاری حمایت می شود . اگر تراکنش جاری وجود نداشته باشد ، خطا رخ می دهد .
- حالت TransactionDefinition.PROPAGATION_NESTED : در این حالت اگر تراکنش جاری وجود داشته باشد به همراه تراکنش درونی آن اجرا می شود .
- حالت TransactionDefinition.PROPAGATION_NEVER : در این حالت تراکنش جاری پشتیبانی نمی شود . اگر تراکنش جاری در سیستم وجود داشته باشد ، خطا رخ می دهد .
- حالت TransactionDefinition.PROPAGATION_NOT_SUPPORTED : در این حالت تراکنش جاری پشتیبانی نشده و برنامه بیشتر اطلاعات ثابت ( non-tranactionally ) را پردازش می کند .
- حالت TransactionDefinition.PROPAGATION_REQUIRED : در این حالت تراکنش جاری پشتیبانی می شود . اگر تراکنشی وجود نداشته باشد ، سیستم یک تراکنش جدید ایجاد می کند .
- حالت TransactionDefinition.PROPAGATION_REQUIRES_NEW : در این حالت برنامه یک تراکنش جدید ایجاد کرده و درصورتی که از قبل تراکنشی وجود داشته باشد ، آن را تعلیق می کند .
- حالت TransactionDefinition.PROPAGATION_SUPPORTS : در این حالت تراکنش جاری اجرا می شود ، ولی اگر تراکنشی وجود نداشته باشد ، اطلاعات ثابت برنامه پردازش می شود .
- حالت TransactionDefinition.TIMEOUT_DEFAULT : در این حالت سیستم از مدت زمان انقضای پیش فرض ( default timeout ) استفاده می کند . اگر هم timeout پشتیبانی نشود ، کاری صورت نمی گیرد .
جدول زیر نیز به بررسی و تشریح مقادیر مختلف ممکن برای Propagation پرداخته است :
رابط کاربری TransactionStatus برای کد تراکنش برنامه یک راه ساده فراهم کرده بتواند اجرای transaction های برنامه و وضعیت جستجوی تراکنش ها را کنترل کند . به صورت کد زیر :
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
در جدول زیر به بررسی متدهای مرتبط با TransactionStatus پرداخته ایم :
- - متد boolean hasSavepoint() : این متد یک مقدار Boolean را برمی گرداند که آیا تراکنش جاری دارای یک savepoint هست یا خیر .
- - متد boolean isCompleted : این متد نیز یک مقدار Boolean را برمی گرداند که آیا تراکنش جاری کامل انجام شده یا خیر . یا اینکه قبلا به صورت کامل ثبت شده یا roll back شده است .
- - متد boolean isNewTransaction : این متد یک مقدار Boolean برمی گرداند که آیا تراکنش جاری یک تراکنش جدید است یا خیر .
- - متد boolean isRollbackOnly : این متد نیز یک مقدار Boolean را برمی گرداند که آیا تراکنش جاری به عنوان یک تراکنش rollback-only ( تراکنشی که بایستی rollback شود. ) تعیین شده یا خیر .
- - متد Void setRollbackOnly : این متد تراکنش جاری را به عنوان یک تراکنش rollback-only تعیین می کند .