Thomas,

== Proposed Solution ==

When adding/changing/removing a property or node, the logical
operation should be recorded on a high level ("this node was added",
"this node was moved from here to there", "this property was added"),
first in memory, but when there are changes, it needs to be persisted
(possibly only temporarily).

When committing a transaction (usually Session.save()), the
micro-kernel tries to apply the changes. If there was a conflict, the
micro-kernel rejects the changes (it doesn't try to merge). The higher
level then has to deal with that. One way to deal with conflict
resolution is:

1) Reload the current persistent state (undo all changes, load the new data).

2) Replay the logical operations from the (in-memory or persisted) journal.

3) If that fails again, depending on a timeout, go to 1) or fail.

I like this approach. In general I think merging is very difficult if not impossible at all to get right and will always be based on some assumptions (intended semantics). I think we should not put this burden onto the micro-kernel but rather leave it to higher levels (or even end users) to do the/some merging.

Regarding 3) I'd include detailed error information on failure: which operations are part of the conflict and what constitutes the conflict. This makes it easier for the consuming API (end user) to resolve conflicts.

== API ==

Instead of the current API that requires the change log to be in
memory, I suggest to use iterators:

Maybe better iterables? More flexible if multiple playbacks are needed.

Michael

Reply via email to