GOODS and data loss when resuming a commit failure

John R. Pierce john at pierce.name
Wed Mar 17 03:41:03 UTC 2004


Hi all,

I have been trying out the GOODS client interface and have had good success
except I am noticing an odd behavior.  I've been doing some conflict testing and
I am getting unexpected results.

Say that client 2 updates an object and client 1 tries to update the same object
just after client 2 commits.  Client 1 will get the KKCommitFailure as
advertised and when rollback is called and retry the block that caused the
conflict -- the object gets saved but all its InstVars are nil in the database.

Here's the code I am running that demonstrates this:

"<SAMPLE>"

 "this script assumes you have an empty GOODS db on localhost port 6001"

 "setup db schema"
 client1 := KKDatabase onHost: 'localhost' port: 6001.
 client1 commitWithRetry: [client1 root: OrderedCollection new].

 "client 2 adds some data"
 client2 := KKDatabase onHost: 'localhost' port: 6001.
 client2 commitWithRetry: [client2 root add: 2 at 2].

 "client 1 doesn't refresh because he didn't know he should -- client 1 adds
some data"
 client1Data := 1 at 1.
 client1 commitWithRetry: [client1 root add: client1Data].

 "client 2 does a refresh to get all changes by other clients"
 client2 refresh.

 "print this line and see there are two elements (as expected)"
 client2 root size.

 "print this next line to see what is in the collection"
 client2 root.

 "it seems like you should get an OrderedCollection(2 at 2 1 at 1)
 but instead you get an OrderedCollection(2 at 2 nil at nil)"

"</SAMPLE>"

KKDatabase>>commitWithRetry: seems to encapsulate the [run some code] on:
KKCommitFailure do: [rollback changes and retry former block].  If you modify
that protocol to [run some code] on: KKCommitFailure do: [drop db connection and
reconnect and retry former block] the problem goes away.

Here's how I modified the sample script to seemingly fix the unexpected problem
-- but it is very much a hack and doesn't feel right to be dropping connections
on a commit conflict.  Am I doing something wrong or do I not understand
something about error handling?

"<FIXED_SAMPLE>"

 client1 := KKDatabase onHost: 'localhost' port: 6001.
 client1 commitWithRetry: [client1 root: OrderedCollection new].

 client2 := KKDatabase onHost: 'localhost' port: 6001.
 client2 commitWithRetry: [client2 root add: 2 at 2].

 client1Data := 1 at 1.
 [client1 root add: client1Data.
 client1 commit] on: KKCommitFailure do: [:ex | client1 := KKDatabase onHost:
'localhost' port: 6001. ex retry].

 client2 refresh.
 client2 root size.

 "print this next line"
 client2 root.

 "in fact you now do get an OrderedCollection(2 at 2 1 at 1)"

"</FIXED_SAMPLE>"

Am I seeing a bug -- any thoughts?

Regards,

John



More information about the Squeak-dev mailing list