如果一个类实现了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