Elmar Weber
2013-01-13 20:07:31 UTC
Hi,
I've been fiddling around with Prevayler and prevalence for some hours
now and worked around most of the kinks. However, how to design the
system and commands to get classical transaction features is still
something I'm not sure about, especially how to get the A in ACID.
Since there is no easy rollback per se and exceptions are ignored and
even replayed, the commands must do all error checking before modifying
any data in the prevalent system. This gets harder to do the more
complex the commands are, e.g. when modifying entities that depend on
each other. And it still does not solve the problem what happens when an
exception occurs in a live system where despite error checking parts of
the transaction are executed and some are not.
How do you work with this, especially, how are the system and commands
designed to mitigate these problems?
I'm currently using a prevalent system class that just holds the state
and only exposes modifying methods to the sub package where the commands
are. The commands then do two things, first perform consistency checks
and then modify the data in the prevalent system when everything is OK.
This works to some degree but does not solve the actual problem
described above (exception after some data has already been modified),
or when executing several simple commands in a compound command.
For a live system where consistency is a fundamental requirement, there
are only two options I could come up with (first one was apparently part
of an older Prevayler version?):
1. "classical" rollback, make copy of system before applying transaction
(relational DBs can optimize this very good with regard to required
memory, to implement this efficiently in a prevalent system would
require some effort)
2. Something along the following lines: when error occurs
- remove/ignore failed transactions from journal
- hold command execution and perform a restore of the system from the
last stored snapshot and journal
- resume command execution
Thanks & regards,
Elmar
I've been fiddling around with Prevayler and prevalence for some hours
now and worked around most of the kinks. However, how to design the
system and commands to get classical transaction features is still
something I'm not sure about, especially how to get the A in ACID.
Since there is no easy rollback per se and exceptions are ignored and
even replayed, the commands must do all error checking before modifying
any data in the prevalent system. This gets harder to do the more
complex the commands are, e.g. when modifying entities that depend on
each other. And it still does not solve the problem what happens when an
exception occurs in a live system where despite error checking parts of
the transaction are executed and some are not.
How do you work with this, especially, how are the system and commands
designed to mitigate these problems?
I'm currently using a prevalent system class that just holds the state
and only exposes modifying methods to the sub package where the commands
are. The commands then do two things, first perform consistency checks
and then modify the data in the prevalent system when everything is OK.
This works to some degree but does not solve the actual problem
described above (exception after some data has already been modified),
or when executing several simple commands in a compound command.
For a live system where consistency is a fundamental requirement, there
are only two options I could come up with (first one was apparently part
of an older Prevayler version?):
1. "classical" rollback, make copy of system before applying transaction
(relational DBs can optimize this very good with regard to required
memory, to implement this efficiently in a prevalent system would
require some effort)
2. Something along the following lines: when error occurs
- remove/ignore failed transactions from journal
- hold command execution and perform a restore of the system from the
last stored snapshot and journal
- resume command execution
Thanks & regards,
Elmar