Is this code snippet correct? My conflict strategy is to choose the latest rev version. I receive the docs with the all-docs query and flag ONLY_CONFLICTS.
private void resolveConflicts(final Document doc, final List<SavedRevision> conflicts) {
if (conflicts.size() > 1) {
// There is more than one current revision, thus a conflict!
CouchbaseUtil.getDatabase().runInTransaction(new TransactionalTask() {
@Override
public boolean run() {
try {
SavedRevision current = doc.getCurrentRevision();
for (SavedRevision rev : conflicts) {
UnsavedRevision newRev = rev.createRevision();
if (!rev.getId().equals(current.getId()))
newRev.setIsDeletion(true);
// saveAllowingConflict allows 'rev' to be updated even if it
// is not the document's current revision.
newRev.save(true);
}
} catch (Exception e) {
return false;
}
return true;
}
});
}
}
This code is run every time the Replication Changelistener fires an event. Is this a good place to do so?
new Replication.ChangeListener() {
@Override
public void changed(Replication.ChangeEvent event) {
// some other code and conflict solving
}
Replication.ChangeListener()'s changed() is fired whenever replication has updates. If you are using continuous replication mode, run conflict resolution when replication state becomes IDLE. If you are using one-shot replication mode, run conflict resolution when replication stopped.
I’m not very familiar with the Java API, but I believe getID returns the document ID, not the revision ID. If so, use getRevID instead. (Is that right, @hideki?)
My conflict strategy is to choose the latest rev version.
That’s not what the code does, actually. The current revision is not necessarily the latest one; it’s just picked basically at random to break a tie. If you really want the latest revision to win, you’ll need to add a timestamp property to the document that gets updated right before it’s saved, and then compare those properties instead. (But be aware that timestamps are not reliable in a distributed system: some devices may have clocks that are accidentally or deliberately wrong.)
Yes, the current revision is always deterministically chosen; that’s important because it ensures that all up-to-date-peers agree on what revision is current.
(The string of characters in the revID is a digest of the contents, so it’s effectively random. The current revision is the one in the highest generation [integer] with the highest digest as compared by strcmp.)