Well, I have to say that Magma completely solves my problems.

I have this seaside code. It calls the user editor. The transaction is kept among several requests. There's no transaction contention since locks are not used and optimistic concurrency control is used instead. You can add and remove groups to the user. If the user cancels, the transaction is aborted and changes are rolled back (automatic undo :)). If the user accepts, then the transaction commits and changes to the user are made effective. If there's a commit error, then the application can handle it. It displays a dialog informing the user of the error and then lets him edit again with a fresh copy.

Sorry if this looks silly to you, but I don't know how to implement this kind of thing in an ORM. I'm the author of a PHP Web/ORM framework but achieving all these things is unfortunately not possible AFAIK.

There's at least one bug in the code. I don't know how to catch the user intention of leaving the component by clicking on another link. If that happens, then the transaction is not aborted nor commited. Leaving the user in an unconsistent state and with a transactionLevelNumber = 1. What's more, later editions will not work because of this (the commit will be ignored as the transactionLevelNumber > 1).

This is the code (note that I'm not a Seaside expert nor a Magma expert):
editObject
    | session |
    session := self session magmaSession.
    session begin.
    [(body
            call: (APUserEditor on: self model))
        ifTrue: [session commit]
        ifFalse: [session abort].
    self viewObject]
        on: MagmaCommitError
        do: [:e |
            session abort.
            self inform: 'The user has been modified by another user. Edit the user again, please'.
            self editObject]


Mariano

2007/6/29, Mariano Montone <marianomontone@gmail.com>:
After having looked at the code, I see that an MagmaCommitConflict exception is raised and an apportunity for the application to decide what to do is given. That is exactly what I wanted. I didn't expect it to be implemented like that (I'm used to some RDBMS worlds where this kind of interaction with the DB is not possible, AFAIK).

This looks very promising!!

I'll be back after doing some tests.

Thanks, Mariano

2007/6/29, Mariano Montone < marianomontone@gmail.com >:
Chris, thanks for answering.  Some comments:

2007/6/28, Chris Muller <asqueaker@gmail.com>:
Hi Mariano, I have a couple of brief comments.

The longer the transaction, the greater chance for for a commit
conflict.  So how should a database handle this? 

I expect the application to decide what to do. Maybe the DB could raise a CommitConflict exception and maybe provide some restarts (ala Common Lisp condition system) for the application to decide how to go on.

I can't speak for others, but Magma doesn't silently restart any
transactions, ever.  That example sounds like mismanagement of a
dirty-read situation.

I'm interested in this one. How does the application gets notified of a transaction need to restart? I think my problems could be solved depending on this.

Thanks, Mariano