Magma Commit Strategies
Last updated at 11:54 pm UTC on 4 January 2010
Q: Where should my application send #begin, #commit, messages?
A: There are several approaches that can be used.
1) Reference the MagmaSession via an instVar of the domain.
A variable which references a MagmaSession when that object is committed will reference the materializing session upon materialization.
This allows programs to be written to say, something like:
self session commit: [ ... ]
This approach can be convenient, but OO purists prefer to have the domain more decoupled from the method of persistence.
2) Program-controlled transactions: You signal commit notifications in your domain. A controller catches these notifications and applies them to its session. When no controller is listening, the notifications are ignored, allowing testing of the domain with or without the database.
name: aString
MagmaSessionRequest signalCommit: [ name := aString ]
This approach gives the program control over when commits are performed. It also allows the user to be free of any concern about remebering to "save"; everything that requires a transaction will be committed without them thinking about it.
To handle the request in your controller code:
[ "... do something..." ]
on: MagmaSessionRequest
do: [ : req | req handleAndResumeUsing: theSession ]
3) User-controlled transactions, with auto-begin: With this approach, the user is always in a transaction. The program provides a "Save" or "Commit" button which the user occasionally presses as they modify the domain model. The program could also provide its own "Cancel" function (which would send #abort, followed by #begin to the MagmaSession) to provide a rudimentary undo function. To use auto-begin, your program does an initial #begin when connecting the session, then every commit should instead use #commitAndBegin instead of #commit. Performance is increased because the #begin step occurs right after the commit automatically with only one trip to the server.