I was thinking about Jon Tirsen's comment on AspectWerkz transaction
performance. AspectWerkz uses Prevayler to persist changes to aspects
and introductions, and it works very nicely - it even supports
transparent persistence to changes made in any java.util Collection!
The performance problem, though, comes from AspectWerkz' use of
Prevayler. Internally, for every setField on an object instance marked
as persistent, AspectWerkz creates a Transaction object and hands it to
Prevayler for persistence. Prevayler synchronously serializes the
transaction object on the tx log, and returns to AspectWerkz. This can
turn out to be a serious performance hit on more transactional systems.
Here's a simple example:
public void populateFoo() { Foo foo = new Foo(); // this object has a persistent introduction
List bars = new ArrayList(100);
for(int i=0; i<100; i++) { bars.add(new Bar()); // Bar also has a persistent introduction }
foo.setBars(bars); }
This small piece of code makes AspectWerkz, Prevayler and your hard
drive work a lot, as a new Transaction object is created for each call
to add(), and another one is created for the final setBars() call. If
you worked with Prevayler you'll know that, by default, it sync()s the
disk after a Transaction object is serialized, to assure that it's
written to disk.
We have a series of Transactions like this:
setField: Bar on ArrayList setField: Bar on ArrayList setField: Bar on ArrayList ... setField: bars on Foo
Today, I dreamed of turning the following a reality:
What would be needed to make this possible? I thought about creating a
setField stack, that would join all those setFields above in a single
transaction. For every setField added, previous state could be added
too, so in the event of an Exception, a rollback could be done
properly, leaving the system always on a consistent state.
Is it possible? I really don't know. But dreams don't need to be possible: that's the main reasons they're always interesting :)