Dear all,

I've been trying out the MagmaCommitConflictError in Magma. I'm experiencing following which I do not understand. 
I've attached a changeset with a test case reproducing the behaviour I do not understand.

If I follow the steps outlined at: http://wiki.squeak.org/squeak/2636 a MagmaCommitConflictError is thrown.
(see testTriggerACommitConflictSequenceAsDescribedOnWiki and a little modification on that: testTriggerACommitConflictLoadObjectBeforeStartingATransaction)

If I however execute 

testTriggerACommitConflictUsersCommitAfterEachOtherButWithTheSameVersionOfObjectInitiallyLoaded

|firstSession secondSession mockObjectRefByFirstSession mockObjectRefBySecondSession|
[firstSession :=
(MagmaRemoteLocation
host: 'localhost'
port: self databasePort) newSession.
firstSession connectAs: 'firstSessionUser'.
firstSession commit: [
firstSession root
at: 'mockObject'
put: (SomeMockDomainObject new aField: 'aField content'; yourself)].

secondSession :=
(MagmaRemoteLocation
host: 'localhost'
port: self databasePort) newSession.
secondSession connectAs: 'secondSessionUser'.

mockObjectRefByFirstSession := firstSession root at: 'mockObject'. "User 1 is loading the object"
mockObjectRefBySecondSession := secondSession root at: 'mockObject'. "User 2 is loading the same version of the object as User 1"

firstSession begin. "1. User 1 begins a transaction."
mockObjectRefByFirstSession aField: 'aField updated by user 1'. "3. User 1 changes Object A."
firstSession commit. "4. User 1 commits his transaction."

secondSession begin. "2. User 2 begins a transaction."
mockObjectRefBySecondSession aField: 'aField updated by user 2'. "5. User 2 changes Object A."

self should: [secondSession commit. "6.7. User 2 commits his transaction"]
raise: MagmaCommitConflictError.

firstSession refresh.

self assert: 'aField updated by user 1' equals: ((firstSession root at: 'mockObject') aField).
self assert: 'aField updated by user 1' equals: ((secondSession root at: 'mockObject') aField).
self assert: 'aField updated by user 1' equals: (mockObjectRefBySecondSession aField).

] ensure: [[firstSession commit: [
firstSession root removeAll].
firstSession disconnect]
ensure:
[secondSession disconnect]]

It failes and I dont understand why. The test is what you get in a typical web application. User 1 has a session on the database. User 2 has another session. Both opened an item. Both are editing it and then first user1 commits his changes. User 2 wants to commit his changes but did not see the updated data of User 1. The test failes at :

self should: [secondSession commit. "6.7. User 2 commits his transaction"] raise: MagmaCommitConflictError.

=> MagmaCommitConflictError is not thrown. Which is something I do not understand. User 2 is trying to commit a change on an object some other session already changed. So User 2 is trying to update a stale version. Is there a reason why no MagmaCommitConflictError is thrown? Furthermore, if you proceed on the failing MagmaCommitConflictError; refresh the firstSession; i notice that the changes made by Session2 effectively got committed; which surprises me even more. Because that means that the changes made by User 1 got overridden by the changes of User 2 without User 2 even knowing.

If I read the information on the wiki, this behaviour is correct since Magma will only detect if during a transaction (after begin has been called) some other session has committed changes on the object being changed. Off course this is not the kind of behaviour you have if you're developing web applications since there, the transactions are very short.

Is there a way to detect if an object was updated by another transaction, but not within my own transaction; so that stale updates do not happen. I suppose there is some version on a persisted object you can check and if the last committed version of an object is higher than the version in the current session, this also means a magmacommitconflicterror? But I havent found any info about that yet?

Thanks for any help.

Kind Regards,

Bart

--
imagination is more important than knowledge - Albert Einstein
Logic will get you from A to B. Imagination will take you everywhere - Albert Einstein
Learn from yesterday, live for today, hope for tomorrow. The important thing is not to stop questioning. - Albert Einstein
The true sign of intelligence is not knowledge but imagination. - Albert Einstein
Gravitation is not responsible for people falling in love. - Albert Einstein