Thursday, May 26, 2011



What is Prevayler?
Prevayler is an open source persistence library for Java. It is an implementation of the Prevalent System architecture pattern, in which data is kept hot in memory with changes journaled for system recovery.

The Prevalent System pattern is illustrated in the diagram shown here. Prevayler [1] serves as a transactional barrier for the business objects [2] of your application, held in memory. You encapsulate all modifications of your business objects into instances of the Transaction interface [3], much like a " command " pattern. Whenever you ask Prevayler to execute a transaction on your business objects [4], Prevayler first writes the transaction object to a journal [5] so that data is not lost if your system crashes. Prevayler can also write a snapshot of your entire business object graph [6] as often as you wish. Prevayler uses the latest snapshot together with the journals to automatically recover your business objects from disk [7] on application startup by restoring the snapshot and then re-executing every transaction that was originally executed after that snapshot was taken.

Why would I use Prevayler?
Well, here are a few of the reasons why we use Prevayler:

1. It ' s extremely simple. There ' s no separate database server to run.

2. It lets us program with real objects. We can choose whatever object models, data structures, and algorithms are appropriate to our particular application domain. Prevayler doesn ' t require our business objects to extend any base class or implement any interface in order to be persistent.

3. It ' s test-friendly. Since we ' re programming with real objects, we can properly encapsulate logic together with the data it uses, making unit tests cleaner, easier to write, and faster to run. The restrictions that Prevayler does impose on us - - keeping our code deterministic, for example - - are consistent with the disciplines that test-driven development teaches us anyway.

4. It makes threadsafety easy. Prevayler makes transactions run sequentially, so we don ' t have to worry about typical multithreading issues like locking and consistency (unless we really want to get tricky, and Prevayler lets us do that, too).

5. It ' s extremely fast. Everything runs in Memory, so the only disk access is streaming transactions to the journal, which we ' ve optimized to a peak rate of up to a thousand transactions per second on desktop hardware. And read-only queries don ' t even have that overhead, so they run instantaneously, hundreds of thousands per second.

What rules do I have to follow?
Prevayler is extremely simple, and imposes very few restrictions on your object model. The only restrictions are to make sure that transaction execution is deterministic and repeatable, so that the exact state of your business objects can be recovered from the transaction journal.

1. All modifications to your business objects must be encapsulated in transaction objects.

2. All your transactions must be completely deterministic. For example, don ' t call System.currentTimeMillis () from within a transaction (or within any business object code called indirectly by a transaction), because it will give a different answer every time the transaction is run. (If you do want to know the time, Prevayler provides an " official " timestamp, assigned when the transaction is first written to the journal. See the Transaction interface.)

Note that any hardware input or output is inherently nondeterministic, and therefore violates this rule. Do all I / O outside of Prevayler transactions.

3. All your transactions and business objects must be serializable, so that they can be written to the journal and snapshot. (You can also configure your own serialization mechanisms if you don ' t want to use Java serialization.)

4. Transactions can ' t carry direct object references (pointers) to business objects. This has become known as the baptism problem because it ' s a common beginner pitfall. Direct object references don ' t work because once a transaction has been serialized to the journal and then deserialized for execution its object references no longer refer to the intended objects - - any objects they may have referred to at first will have been copied by the serialization process! Therefore, a transaction must carry some kind of string or numeric identifiers for any objects it wants to refer to, and it must look up the objects when it is executed.

Download
Download Prevayler 2.3, containing code, documentation and demos.

You can also join the Prevayler mailing lists.

If you have any questions or problems using Prevayler, please post on the prevayler-discussion mailing list, not the comments section here - - you'll get a much quicker response.

See: Links, Prevalent Hypothesis, Baptism Problem, Memory Technology, Prevayler Examples

[[This new wiki is still under construction. An earlier draft of this front page is here.]]

No comments: