# Optimistic Concurrency on new documents

**URL:** <https://discuss.elastic.co/t/optimistic-concurrency-on-new-documents/182110>\
**Category:** Elasticsearch\
**Created:** [May 22, 2019, 12:57am UTC](https://discuss.elastic.co/t/optimistic-concurrency-on-new-documents/182110 "2019-05-22T00:57:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dferretti3](https://avatars.discourse-cdn.com/v4/letter/d/35a633/32.png) [@dferretti3](https://discuss.elastic.co/u/dferretti3)\
**Post date:** [May 22, 2019, 12:57am UTC](https://discuss.elastic.co/t/optimistic-concurrency-on-new-documents/182110/1 "2019-05-22T00:57:58Z")

</div>

I have a process that will perform the following steps in response to a message being received:

- Attempt to get a document, include seq\_no and primary\_term if found
- Create a new document, based on the results of some in-memory merge of the received message and (optionally) the retrieved document
- Index the new document to the same ID, using the previous seq\_no/primary\_term or leaving them off if not found to make use of the optimistic locking that ES provides.

If a document already exists at a certain ID, and 2 messages are then received concurrently, the process works fine:

- message 1 received, gets document from ES with seq\_no/primary\_term
- message 2 received, gets same document with same seq\_no/primary\_term
- either process finishes first, and is able to save the new document
- whichever process is slower will fail due to VersionConflictEngineException - I can retry or otherwise handle this myself now

If the document does not exist though, and 2 messages are received concurrently, the process fails:

- message 1 received, finds no document in ES so has no seq\_no or primary\_term
- message 2 received, also finds no document in ES
- either process finishes first, and saves new document, leaving off seq\_no/primary\_term
- whichever process is slower will also be able to save since it also leaves off seq\_no/primary term. but I would like this save to fail

It would be nice if you could provide (0,0) as a starting point or something similar, so you can represent the notion of "index only if document doesn't exist".

I have dug through the elasticsearch source a bit and this seems to be where it does the version check: [https://github.com/elastic/elasticsearch/blob/57859413eaf1f59357eb6a9875ca0ae51a76bbb3/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java#L992](https://github.com/elastic/elasticsearch/blob/57859413eaf1f59357eb6a9875ca0ae51a76bbb3/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java#L992)  
Looks like if you provide any seq\_no/primary\_term at all, but the index does not contain the document yet, it will always fail - so there is not valid value (like 0,0) you can send for a nonexistent document. All you can do is leave it unassigned which leaves you back where I described above.

---

<div class="post-metadata">

**Author:** ![dferretti3](https://avatars.discourse-cdn.com/v4/letter/d/35a633/32.png) [@dferretti3](https://discuss.elastic.co/u/dferretti3)\
**Post date:** [May 22, 2019, 1:01am UTC](https://discuss.elastic.co/t/optimistic-concurrency-on-new-documents/182110/2 "2019-05-22T01:01:24Z")

</div>

This turned out to be a good rubber duck debugging session - as I was typing this out, the "index only if document doesn't exist" clued me in to what was missing. So here is how I solved it in case it helps anyone else:

In the event the document wasn't found, don't use seq\_no/primary\_term. Instead use op\_type = create, which does exactly what I was looking for (index only if it doesn't exist already). You can still catch the 409 Conflict response type with that.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 19, 2019, 1:08am UTC](https://discuss.elastic.co/t/optimistic-concurrency-on-new-documents/182110/3 "2019-06-19T01:08:10Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
