For the rest of this chapter, we will consider the following problem—suppose we are implementing a database of records. The records are stored on disk, but there is also an in-memory index for fast access to the records. The database API offers a method to insert records into the database:
class Record { ... };class Database { public: void insert(const Record& r); ...};
If the insertion succeeds, both the index and the disk storage are updated and are consistent with each other. If something goes wrong, an exception is thrown.
While it appears to the clients of the database that the insertion is a single transaction, the implementation has to deal with the fact that it is done in multiple steps—we need to ...