Hello
I am using Couchbase Server in version 4.5.1 and Couchbase Javva client version 2.4.6. I thought that updates in different parts of the document (subdoc operations) in parallel are supported, but the behaviour I observed in the tests is strange. When executing code which updates four different parts of document, like below:
@Test
public void shouldUpdatePartsOfDocumentsParralel() throws InterruptedException
{
//configuration
final int updatesCount = 1;
//given
final JsonObject data = prepareDocument();
final String docuId = "documentXYZ";
final List updates = Stream.of("map1", "map2", "map3", "firstName") //
.map( path -> (Callable) () ->
{
final long updatingStartDate = System.currentTimeMillis();
System.out.println(String.format("Updating for %s started %d ms", path, updatingStartDate));
IntStream.rangeClosed(0, updatesCount).boxed().forEach(i ->
{
try
{
bucket.mutateIn(docuId).upsert(path, i).withDurability(PersistTo.ONE).execute();
}
catch (final Exception e)
{
System.out.println(path + " " + e.getMessage());
}
});
final long updatingEndDate = System.currentTimeMillis();
return "";
}).collect(Collectors.toList());
final ExecutorService executorService = Executors.newWorkStealingPool(updates.size());
//CREATING DOCUMENT
//when
final JsonDocument document = JsonDocument.create(docuId, data);
try {
bucket.upsert(document);
} catch (final Exception e) {
System.out.println("Error during creating document" + e.getMessage());
throw e;
}
//UPDATING DOCUMENT
executorService.invokeAll(updates)
.stream()
.map(future -> {
try {
return future;
}
catch (Exception e) {
throw new IllegalStateException(e);
}
})
.forEach(System.out::println);
System.out.println("After test received document: " + bucket.get(docuId).content().toMap());
}
The output is:
Updating for map1 started 1499858844353 ms
Updating for firstName started 1499858844353 ms
Updating for map2 started 1499858844353 ms
Updating for map3 started 1499858844353 ms
firstName com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
map3 com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
map2 com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
map1 com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
firstName com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
map3 com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
map2 com.couchbase.client.java.error.DurabilityException: Durability requirement failed: The CAS on the active node changed for ID "documentXYZ", indicating it has been modified in the meantime.
After test received document: {firstName=1, lastName=Brzęczyszczykiewicz, map3=1, map2=1, map1=1}
I am receiving exception on each attempt to updating the document, but surprisingly all changes are saved into document. Could someone explain what is the cause of this behaviour and what I am doing wrong?
Thanks for help!
Regards
Sebastian