SOLR-10734: AtomicUpdateRequestProcessor can cause wrong/old values to be set under concurrent updates for the same document. Multithreaded test for AtomicUpdateRequestProcessor was also beefed up and fixed.

This commit is contained in:
Shalin Shekhar Mangar 2018-03-28 12:40:57 +05:30
parent 3e29c7dbd5
commit ab32506243
3 changed files with 20 additions and 12 deletions

View File

@ -86,6 +86,10 @@ Bug Fixes
* SOLR-12035: ExtendedDismaxQParser fails to include charfilters in nostopanalyzer (Tim Allison via
Tomás Fernández Löbbe)
* SOLR-10734: AtomicUpdateRequestProcessor can cause wrong/old values to be set under concurrent updates for the same
document. Multithreaded test for AtomicUpdateRequestProcessor was also beefed up and fixed.
(Ishan Chattopadhyaya, Noble Paul, Amrit Sarkar, shalin)
Optimizations
----------------------
@ -122,8 +126,6 @@ Other Changes
* SOLR-12118: Solr Ref-Guide can now use some ivy version props directly as attributes in content (hossman)
* SOLR-10734: Multithreaded test/support for AtomicURP broken. (Ishan Chattopadhyaya, Noble Paul, Amrit Sarkar, shalin)
================== 7.3.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -153,17 +153,17 @@ public class AtomicUpdateProcessorFactory extends UpdateRequestProcessorFactory
// if atomic, put _version_ for optimistic concurrency if doc present in index
if (isAtomicUpdateAddedByMe) {
Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId());
if (lastVersion != null) {
orgdoc.setField(VERSION, lastVersion);
}
processAddWithRetry(cmd, 0);
// if lastVersion is null then we put -1 to assert that document must not exist
lastVersion = lastVersion == null ? -1 : lastVersion;
orgdoc.setField(VERSION, lastVersion);
processAddWithRetry(cmd, 1, cmd.getSolrInputDocument().deepCopy());
} else {
super.processAdd(cmd);
}
// else send it for doc to get inserted for the first time
}
private void processAddWithRetry(AddUpdateCommand cmd, int attempts) throws IOException {
private void processAddWithRetry(AddUpdateCommand cmd, int attempts, SolrInputDocument clonedOriginalDoc) throws IOException {
try {
super.processAdd(cmd);
} catch (SolrException e) {
@ -174,11 +174,18 @@ public class AtomicUpdateProcessorFactory extends UpdateRequestProcessorFactory
if (e.code() == ErrorCode.CONFLICT.code) { // version conflict
log.warn("Atomic update failed due to " + e.getMessage() +
" Retrying with new version .... (" + attempts + ")");
Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId());
if (lastVersion != null) {
cmd.solrDoc.setField(VERSION, lastVersion);
}
processAddWithRetry(cmd, attempts);
// if lastVersion is null then we put -1 to assert that document must not exist
lastVersion = lastVersion == null ? -1 : lastVersion;
// The AtomicUpdateDocumentMerger modifies the AddUpdateCommand.solrDoc to populate the real values of the
// modified fields. We don't want those absolute values because they are out-of-date due to the conflict
// so we restore the original document created in processAdd method and set the right version on it
cmd.solrDoc = clonedOriginalDoc;
cmd.solrDoc.setField(VERSION, lastVersion);
processAddWithRetry(cmd, attempts, clonedOriginalDoc);
}
}
}

View File

@ -198,7 +198,6 @@ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
}
@BadApple(bugUrl = "https://issues.apache.org/jira/browse/SOLR-10734")
public void testMultipleThreads() throws Exception {
clearIndex();
String[] strings = new String[5];