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 * SOLR-12035: ExtendedDismaxQParser fails to include charfilters in nostopanalyzer (Tim Allison via
Tomás Fernández Löbbe) 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 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-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 ================== ================== 7.3.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. 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 atomic, put _version_ for optimistic concurrency if doc present in index
if (isAtomicUpdateAddedByMe) { if (isAtomicUpdateAddedByMe) {
Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId()); Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId());
if (lastVersion != null) { // if lastVersion is null then we put -1 to assert that document must not exist
orgdoc.setField(VERSION, lastVersion); lastVersion = lastVersion == null ? -1 : lastVersion;
} orgdoc.setField(VERSION, lastVersion);
processAddWithRetry(cmd, 0); processAddWithRetry(cmd, 1, cmd.getSolrInputDocument().deepCopy());
} else { } else {
super.processAdd(cmd); super.processAdd(cmd);
} }
// else send it for doc to get inserted for the first time // 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 { try {
super.processAdd(cmd); super.processAdd(cmd);
} catch (SolrException e) { } catch (SolrException e) {
@ -174,11 +174,18 @@ public class AtomicUpdateProcessorFactory extends UpdateRequestProcessorFactory
if (e.code() == ErrorCode.CONFLICT.code) { // version conflict if (e.code() == ErrorCode.CONFLICT.code) { // version conflict
log.warn("Atomic update failed due to " + e.getMessage() + log.warn("Atomic update failed due to " + e.getMessage() +
" Retrying with new version .... (" + attempts + ")"); " Retrying with new version .... (" + attempts + ")");
Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId()); Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId());
if (lastVersion != null) { // if lastVersion is null then we put -1 to assert that document must not exist
cmd.solrDoc.setField(VERSION, lastVersion); lastVersion = lastVersion == null ? -1 : lastVersion;
}
processAddWithRetry(cmd, attempts); // 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 { public void testMultipleThreads() throws Exception {
clearIndex(); clearIndex();
String[] strings = new String[5]; String[] strings = new String[5];