如果某個類別實作了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存取資料庫的狀態。
資料庫的狀態可以設為下列其中一種:
實作Orm.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
在Orm類別上實作IDisposable介面。這個呼叫保證會成功。
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