اگر یک «کلاس» «رابط» IDisposable را پیادهسازی کند، هر زمان که دیگر به نمونهای نیاز نباشد، باید متد Dispose() آن فراخوانی شود. این کار معمولاً در بند catch یا finally انجام میشود، یا از رویهی Dispose() یکی از فراخوانندهها. Dispose() فرصتی فراهم میکند تا منابع مدیریتنشده، مانند اشیای سیستم عامل (که توسط زمان اجرای .NET مدیریت نمیشوند)، آزاد شوند و وضعیت داخلی منابع مدیریتشده بازنشانی شود.
شما در حال پیادهسازی یک سیستم ORM (نگاشت شیء-رابطهای) روی یک پایگاه داده هستید که تیم دیگری آن را فراهم کرده است.
پایگاه داده در هر لحظه میتواند تنها یک تراکنش را مدیریت کند.
در این مرحله نیازی به لاگگیری یا هر نوع رسیدگی به خطای دیگری نیست.
توجه داشته باشید که پایگاه داده بهصورت داخلی از میان چندین وضعیت عبور میکند: Closed، TransactionStarted، DataWritten، Invalid، Closed. میتوانید مطمئن باشید که پایگاه داده در آغاز هر تمرین در وضعیت Closed قرار دارد.
پایگاه داده متدهای نمونهی زیر را دارد:
Database.BeginTransaction() یک تراکنش روی پایگاه داده آغاز میکند. اگر این متد زمانی فراخوانی شود که پایگاه داده در وضعیت Closed نباشد، یک استثنا پرتاب میشود. در صورت موفقیت، وضعیت داخلی پایگاه داده به TransactionStarted تغییر میکند.Database.Write(string data) داده را درون تراکنش در پایگاه داده مینویسد. اگر دادهی نامعتبری دریافت کند، استثنایی پرتاب میشود. تلاش برای فراخوانی این متد پیش از فراخوانی BeginTransaction() باعث پرتاب استثنا میشود. در صورت موفقیت، وضعیت داخلی پایگاه داده به DataWritten تغییر میکند.Database.EndTransaction() تراکنش را در پایگاه داده ثبت میکند. ممکن است در صورتی که نتواند تراکنش را ببندد یا Database.BeginTransaction() فراخوانی نشده باشد، استثنا پرتاب کند.Database.Dispose() در صورتی که در جریان یک تراکنش استثنایی پرتاب شود، پایگاه داده را پاکسازی میکند. این کار وضعیت پایگاه داده را به Closed تغییر میدهد.وضعیت پایگاه داده را میتوان با database.DbState مشاهده کرد.
وضعیت پایگاه داده را میتوان به یکی از این مقادیر تنظیم کرد:
TransactionStartedDataWrittenInvalidClosedOrm.Begin() را پیادهسازی کنید تا یک تراکنش روی پایگاه داده آغاز شود. اگر پایگاه داده با وضعیت داخلی State.Closed شروع نشود، یک InvalidOperationException پرتاب میکند.
var orm = new Orm(new Database());
orm.Begin();
// => database has an internal state of State.TransactionStarted
Orm.Write() را پیادهسازی کنید تا مقداری داده در پایگاه داده نوشته شود. اگر پایگاه داده با وضعیت داخلی State.TransactionStarted شروع نشود یا دادهی نامعتبری نوشته شود، یک InvalidOperationException پرتاب میشود. اگر نوشتن شکست بخورد، Orm باید پایگاه داده را پاکسازی کند.
var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
// => database has an internal state of State.DataWritten
orm.Write("bad write");
// => database has an internal state of State.Closed
Orm.Commit() را پیادهسازی کنید تا داده ثبت شود. اگر ثبت شکست بخورد، پایگاه داده را پاکسازی کنید. اگر پایگاه داده با وضعیت داخلی State.DataWritten شروع نشود، یک InvalidOperationException پرتاب میشود.
var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
orm.Commit();
// => database has an internal state of State.Closed
orm.Begin();
orm.Write("bad commit");
orm.Commit();
// => database has an internal state of State.Closed
رابط IDisposable را روی کلاس Orm پیادهسازی کنید. این فراخوانی قطعاً موفق خواهد شد.
var db = new Database();
var orm = new Orm(db);
orm.Begin();
orm.Write("some data");
orm.Dispose();
// => database has an internal state of State.Closed