We have talked about making UnitOfWork more eventoriented, and indeed,
the basic idea of a UnitOfWork is to create a "work log". But, this is
not how it has been implemented so far. Instead a UoW has loaded
snapshots (EntityState), updated those snapshots, and then sent them
back to the EntityStore, but without any information about what
happened. I have now realized that this is bad, for all sorts of reasons.
Here's what I suggest we do: on the EntityStore we create this method:
EntityStoreUnitOfWork newUnitOfWork()
This creates a new change tracker, and it is also from this that the
UnitOfWork acquires EntityState's. This methods is called once for every
EntityStore, for every UnitOfWork that needs it. The
newEntityState/getEntityState methods are moved to EntityStoreUnitOfWork.
When EntityStates are updated, by calling
setProperty/setAssociation/manyAssociationState.add etc. these changes
are tracked in the EntityStoreUnitOfWork as events. The ESUOW in this
way creates a series of UnitOfWorkChanges, which is kept internally.
The ESUOW can also optionally track read-events. This would help ensure
that when the command is written we can check that the read state has
not changed.
When the UnitOfWork commits the ESUOW is sent to the prepare() method of
EntityStore, which hence changes to:
void prepare(EntityStoreUnitOfWork uow);
The implementation of ESUOW is custom for the EntityStore, and so the
EntityStore can internally cast it to potentially get more information.
Extra information that the EntityStore might want to keep includes the
id of the UnitOfWork, the name of the Usecase, meta information from the
UoW and Usecase, etc.
For transaction-wrapped UnitOfWorks (i.e. a transaction is created
outside of the UnitOfWork), this abstraction also makes it possible for
the EntityStore to keep the transaction reference in the ESUOW (Neo4j,
I'm talking about you!).
Another possibility is that this makes it easier to do lazy-loading of
state. So even if you have acquired an EntityState the actual state
might not yet have been loaded from the underlying store.
It also makes it possible to do copy-on-write EntityStates, which could
improve performance a LOT in read-intensive cases (i.e. load and cache
one shared EntityState per identity.
Continued in part 3.
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev