Magma Transactions - MagmaCommitConflictError

Chris Muller asqueaker at gmail.com
Thu Dec 10 19:44:24 UTC 2009


Hi, the should: raise: MagmaCommitConflictError in
#testTriggerACommitConflictUsersCommitAfterEachOtherButWithTheSameVersionOfObjectInitiallyLoaded
:

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

fails because secondSession crossed a transaction boundary (via its
#begin) after firstSession's commit.  Second session would see the
results of firstSession's commit, and therefore there is no conflict.
A commit-conflict would have occurred if secondSession had sent #begin
BEFORE firstSession's commit..

Regards,
  Chris


On Tue, Dec 8, 2009 at 2:18 PM, Bart Gauquie <bart.gauquie at gmail.com> wrote:
> 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
>
> _______________________________________________
> Magma mailing list
> Magma at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/mailman/listinfo/magma
>
>


More information about the Magma mailing list