You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Oren Shani <or...@gmail.com> on 2011/05/20 15:46:50 UTC

Resolving a classical conflict in CouchDB - Looking for best practices / advise

Hi All,


I am developing a concurrent application in Ruby, that make use of a 
shared data space that will be much easier to implement over CouchDB 
than over an RDBMS. I was playing around with Couch Potato and I find it 
to be almost perfect for my needs, except for one, but very critical, 
conflict issue. I wonder if you could advise me on the best way to 
handle this.


In principle, I need my applications to use a function similar to this one:


def foa(index)

    keyhash = CouchPotato.database.load_document "keyhash_id"


    if (keyhash[index].isnil?)

       keyhash[index] = keyhash.size

CouchPotato.database.save_document keyhash

    end


    return (keyhash[index])

end


The problem is that if I have to applications calling the function 
concurrently, it might end up with a conflict, and then the document in 
the database will have for example keyhash["abcd"] =5 /or 
/keyhsah["efgh"] = 5 instead of keyhash["abcd"] = 5 /and/ 
keyhash["efgh"] = 6 (this is a rather classical concurrency conflict 
problem so I suppose you understand what I mean...)


I suppose I could build some checkout/checkin mechanism that will 
involve more documents and communication with the DB server, but again, 
I rather use something which is a common practice, so I'd be happy to 
get some advice.


Many thanks,


Oren Shani


Re: Resolving a classical conflict in CouchDB - Looking for best practices / advise

Posted by Jonathan Weiss <jw...@innerewut.de>.
> I am trying to implement what you suggested which fits very well with my
> model. I have one question tough (to Oern or to anyone who may know) - how
> do I access the older revisions? Couch Potato does not seem to have a direct
> method for doing that, I asked in Upstream's website but I'd appreciate it
> if someone here can help too

In SimplyStored (wrapper around CouchPotato) we automatically try to
merge a conflict on a failed save. If this doesn't work, we expose the
conflict exception to the user.

Jonathan


-- 
Jonathan Weiss
http://blog.innerewut.de
http://twitter.com/jweiss

Re: Resolving a classical conflict in CouchDB - Looking for best practices / advise

Posted by Oren Shani <or...@gmail.com>.
Owen,

I think I will not need the old revisions after all. This is because 
what happens with Couch Potato is this:

1) Client 1 reads revision 1 , changes the doc content and saves - 
revision 2 is created
2) Client 2 reads revision 1 in parallel to client 2, changes the 
content and tries to save - Couch Potato raises a conflict exception

So now all client 2 has to do is to read revision 2, resolve the 
conflict between what client 1 wrote (in revision 2) to what it was 
attempting to write and save ( revision 3 will be created).

Thanks for your help

Oren

On 06/02/2011 05:31 PM, Owen Marshall wrote:
> At Sat, 28 May 2011 09:25:07 +0300,
> Oren Shani wrote:
>
>> I have one question tough (to Oern or to anyone who may know) -
>> how do I access the older revisions?
> For the plain HTTP API:
>
> GET /db/document_id?rev=old_rev_id
> You can also GET /db/document_id?open_revs=["r1", "r2", ...] and CouchDB will return those full revisions in an array.
> See http://wiki.apache.org/couchdb/HTTP_Document_API for more.
>
> Unfortunately I haven't used Couch Potato so I can't help there... surely though there is a way to pass in extra parameters, and I'd try throwing in a {'rev': 'blah'} there.
>


Re: Resolving a classical conflict in CouchDB - Looking for best practices / advise

Posted by Owen Marshall <om...@facilityone.com>.
At Sat, 28 May 2011 09:25:07 +0300,
Oren Shani wrote:

> I have one question tough (to Oern or to anyone who may know) - 
> how do I access the older revisions?

For the plain HTTP API:

GET /db/document_id?rev=old_rev_id
You can also GET /db/document_id?open_revs=["r1", "r2", ...] and CouchDB will return those full revisions in an array.
See http://wiki.apache.org/couchdb/HTTP_Document_API for more.

Unfortunately I haven't used Couch Potato so I can't help there... surely though there is a way to pass in extra parameters, and I'd try throwing in a {'rev': 'blah'} there.

-- 
Owen Marshall
FacilityONE
http://www.facilityone.com | (502) 805-2126


Re: Resolving a classical conflict in CouchDB - Looking for best practices / advise

Posted by Oren Shani <or...@gmail.com>.
Thanks Owen,

I am trying to implement what you suggested which fits very well with my 
model. I have one question tough (to Oern or to anyone who may know) - 
how do I access the older revisions? Couch Potato does not seem to have 
a direct method for doing that, I asked in Upstream's website but I'd 
appreciate it if someone here can help too

BR,

Oren

On 05/20/2011 05:19 PM, Owen Marshall wrote:
> On 05/20/2011 09:46 AM, Oren Shani wrote:
>> The problem is that if I have to applications calling the function
>> concurrently, it might end up with a conflict, and then the document in
>> the database will have for example keyhash["abcd"] =5 /or
>> /keyhsah["efgh"] = 5 instead of keyhash["abcd"] = 5 /and/
>> keyhash["efgh"] = 6 (this is a rather classical concurrency conflict
>> problem so I suppose you understand what I mean...)
> GET your document with conflicts=true. If there are any conflicting
> revisions, GET those revisions as well. Then just merge together in a
> single document, write that correct document, and delete the conflicting
> revisions. I use a single POST to _bulk_docs for that part.
>
> See:
> http://wiki.apache.org/couchdb/Replication_and_conflicts
>


Re: Resolving a classical conflict in CouchDB - Looking for best practices / advise

Posted by Owen Marshall <om...@facilityone.com>.
On 05/20/2011 09:46 AM, Oren Shani wrote:
> The problem is that if I have to applications calling the function
> concurrently, it might end up with a conflict, and then the document in
> the database will have for example keyhash["abcd"] =5 /or
> /keyhsah["efgh"] = 5 instead of keyhash["abcd"] = 5 /and/
> keyhash["efgh"] = 6 (this is a rather classical concurrency conflict
> problem so I suppose you understand what I mean...)

GET your document with conflicts=true. If there are any conflicting
revisions, GET those revisions as well. Then just merge together in a
single document, write that correct document, and delete the conflicting
revisions. I use a single POST to _bulk_docs for that part.

See:
http://wiki.apache.org/couchdb/Replication_and_conflicts

-- 
Owen Marshall
FacilityONE
http://www.facilityone.com | (502) 805-2126