The ACID properties

Our design must consider how the ACID properties apply to our shelve database. Often, an application will make changes in bundles of related operations; the bundle should change the database from one consistent state to the next consistent state. The intent of a transactional bundle is to conceal any intermediate states that may not be consistent with other users of the data.

An example of multiple-operation transactions could involve updating two objects so that a total is kept invariant. We might be deducting funds from one financial account and depositing into another. The overall balance must be held constant for the database to be in a consistent, valid state.

The ACID properties characterize how we want the database transactions to behave as a whole. There are four rules that define our expectations:

  • Atomicity: A transaction must be atomic. If there are multiple operations within a transaction, either all the operations should be completed or none of them should be completed. It should never be possible to view a partially completed transaction.
  • Consistency: A transaction must assure consistency of the overall database. It must change the database from one valid state to another. A transaction should not corrupt the database or create inconsistent views among concurrent users. All users see the same net effect of completed transactions.
  • Isolation: Each transaction should operate as if it processed in complete isolation from all other transactions. We can't have two concurrent users interfering with each other's attempted updates. We should always be able to transform concurrent access into (possibly slower) serial access and the database updates will produce the same results. Locks are often used to achieve this.
  • Durability: The changes to the database should persist properly in the filesystem.

When we work with in-memory Python objects, clearly, we can get ACI, but we don't get D. In-memory objects are not durable by definition. If we attempt to use the shelve module from several concurrent processes without locking or versioning, we may get only D, but lose the ACI properties.

The shelve module doesn't provide direct support for atomicity; it lacks an integrated technique to handle transactions that consist of multiple operations. If we have multiple-operation transactions and we need atomicity, we must ensure that they all work or all fail as a unit. This can involve saving the state prior to a try: statement; in the event of a problem, the exception handlers must restore the previous state of the database.

The shelve module doesn't guarantee durability for all kinds of changes. If we place a mutable object onto the shelf and then change the object in memory, the persistent version on the shelf file will not change automatically. If we're going to mutate shelved objects, our application must be explicit about updating the shelf object. We can ask a shelf object to track changes via the writeback mode, but using this feature can lead to poor performance.

These missing features are relatively simple to implement with some additional locking and logging. They aren't default features of a shelf instance. When full ACID capabilities are needed, we often switch to other forms of persistence. When an application doesn't need the full ACID feature set, however, the shelve module can be very helpful.

In the next section, we'll see how to create a shelf.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset