Hi,
I'm working on the EventSourcing library, and have a bit of trouble with
the algorithm of UoW completion.
Basically, since the EventStore is my "single source of truth" I need to
have it commit its events before the EntityStore is committed. That way,
if the events are committed but the entities not, I can always replay
the events to get the EntityStore up to date with "what really
happened". Same with the index.
This is not possible right now, since the complete() algorithm looks
like so:
public void complete()
throws UnitOfWorkCompletionException
{
checkOpen();
// Copy list so that it cannot be modified during completion
List<UnitOfWorkCallback> currentCallbacks = callbacks == null ?
null : new ArrayList<UnitOfWorkCallback>( callbacks );
// Check callbacks
notifyBeforeCompletion( currentCallbacks );
// Commit state to EntityStores
List<StateCommitter> committers = applyChanges();
// Commit all changes
for (StateCommitter committer : committers)
{
committer.commit();
}
close();
// Call callbacks
notifyAfterCompletion( currentCallbacks, COMPLETED );
callbacks = currentCallbacks;
}
----
The EntityStore needs to do two things: check for concurrency errors and
store state. Concurrency checks happen in applyChanges() as it is now,
and then state is committed on commit(). But since
notifyBeforeCompletion() happens before applyChanges() I can't store
events there, as there might be a concurrency failure from
applyChanges(). So right now it happens in notifyAfterCompletion, which
means that if the event-storing throws an exception there's nothing I
can do to rollback the entity state. This only happens on system
failures (e.g. write to disk failed), but is still an issue
theoretically speaking.
So, to fix this I would suggest that notifyBeforeCompletion moves to
after applyChanges, so that it can know that there won't be any
concurrency exceptions later. If any callback then throws a
UnitOfWorkCompletionException it would result in committer.cancel()
being called on all EntityStores (which for most cases does nothing).
Is this an ok change to make, or do you see any issues with invoking
callbacks after applyChanges()?
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev