Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving replication conflicts for deleted documents in CouchDB

The way of resolving replication conflicts recommended by official documentation is:

  1. Read conflicting revisions using document's _conflicts field (e.g. via a view)
  2. Fetch docs for all revisions listed
  3. Perform application-specific merging
  4. Remove unwanted revisions

The problem comes in when I want to merge deleted documents. They do not show up in _conflicts field, but in _deleted_conflicts. If I merge only using _conflicts field, and a document is deleted in the local database and edited in the remote replica, it will be resurrected locally on replication. My application model assumes that deletion always takes precedence when merging: a deleted documents stays deleted regardless of what edits it conflicts with.

So, at a first glance, the simplest thing to do is to check that _deleted_conflicts is not empty and if it is not empty, delete the document, right? Well... the problem with this is that this may also contain deleted revisions that were introduced by resolving edit conflicts in step #4, so the meaning of _deleted_conflicts is ambiguous in this case.

What's the canonical way of handling deletion conflicts in CouchDB (if any) that doesn't involve doing gross things like marking documents as deleted and filtering at the application layer?

like image 268
Alex B Avatar asked Oct 24 '12 06:10

Alex B


1 Answers

The best solution would be to use the reserved property _deleted to remove documents instead of HTTP DELETE. Then you are free to also set other properties:

doc._deleted = true;
doc.deletedByUser = true;
doc.save();

Then in the merge process check the _changes feed for _deleted_conflicts and delete the document if there is a revision within _deleted_conflicts that has the deletedByUser flag set to true.

I hope this helps!

like image 77
Bernhard Gschwantner Avatar answered Sep 22 '22 09:09

Bernhard Gschwantner