Orthogonal persistence

Many researchers have commented on the ideology of orthogonal persistence.

Orthogonal persistence allows the programmer to treat all objects in the same way - whether they persist or not. An object is able to persist regardless of its type. In the context of OO systems an object persists if it is reachable from another persistent object.

A system can provide orthognal persistence to varying degrees. In the most extreme case, the programmer should not need to write transactions to break up work into atomic pieces. Instead, all threads are persistent so it can be assumed that on recovery a computation will carry on from where it left off. This is far from easy to implement efficiently. To support persistent threads, it is necessary for a system to look for a consistent cut on recovery. There can easily be a domino effect where the last "consistent cut" occurred a long time in the past.

Persistence and concurrency control don't mix well. This is to be expected because adding concurrency control to persistent objects implies that persistent objects are treated differently to transient objects - in conflict with the principle of orthogonal persistence. When a class is written and no mutexes etc are used for concurrency control, it is understood that objects of that class are not threadsafe. One would expect this to be independent of whether the object is reachable from a persistent root.

Consider a system where accessing the state of a persistent object can throw an exception. If the programmer doesn't distinguish between persistent and transient objects, then it follows that it must be assumed that access to any object can throw an exception. This is unworkable - because it becomes impossible to reason about the correctness of a program.

Consider that a process supports more than one independent persistent store - because of multiple hard-disks or floppy disks. This leads to confusion - what does it mean for an object to be reachable from two independent persistent stores? From which store is it loaded when it is next accessed? What if the object exists in inconsistent states on different media? What if one media rolls back and another doesn't? The conclusion is that multiple independent persistent stores within a given process are incompatible with orthogonal persistence.

A significant problem with the ideology of orthogonal persistence is the question of how to make changes to the system. If state such as threads persist then it is very difficult to see how to fix bugs, allow classes to add or remove members or implement new interfaces. It is as though we are trying to change as system while it is still running.

The latter is such a difficult problem, it would appear that the ideology of orthogonal persistence (at least in its true form) is unworkable.

In Praise of Manual Persistence provides a good description of some of the problems with orthogonal persistence.

A very amusing quote on that page:

Do you, Programmer, take this Object to be part of the persistent state of your application, to have and to hold, through maintenance and iterations, for past and future versions, as long as the application shall live?

How CEDA breaks othogonal persistence

The ceda design recognises that the ideology of orthogonal persistence offers some advantages, but intentionally breaks with the principle in certain respects.

How CEDA supports orthogonal persistence

However the principle of orthogonal persistence is adhered to in the following respects