Highlighted

javax.jcr.InvalidItemStateException: OakState0001: Unresolved conflicts in asset when publishing

radhakrishnan72

25-01-2018

Hi everyone,

                     i use replication API to replicate assets from author to publishers. As part of replication process and after calling replicate(), I see following exception many times in a day for many assets,

om.day.cq.replication.ReplicationException: javax.jcr.InvalidItemStateException: OakState0001: Unresolved conflicts in path/to/asset/metadata

at com.day.cq.replication.impl.ReplicatorImpl.replicate(ReplicatorImpl.java:517)

Caused by: javax.jcr.InvalidItemStateException: OakState0001: Unresolved conflicts in  path/to/asset/metadata

at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:237)

at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:212)

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryException(SessionDelegate.java:670)

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:496)

at org.apache.jackrabbit.oak.jcr.session.SessionImpl$8.performVoid(SessionImpl.java:419)

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.performVoid(SessionDelegate.java:274)

at org.apache.jackrabbit.oak.jcr.session.SessionImpl.save(SessionImpl.java:416)

at com.day.cq.replication.impl.ReplicatorImpl.replicate(ReplicatorImpl.java:471)

... 14 common frames omitted

Caused by: org.apache.jackrabbit.oak.api.CommitFailedException: OakState0001: Unresolved conflicts in path/to/asset/metadata

at org.apache.jackrabbit.oak.plugins.commit.ConflictValidator.failOnMergeConflict(ConflictValidator.java:115)

at org.apache.jackrabbit.oak.plugins.commit.ConflictValidator.propertyAdded(ConflictValidator.java:84)

at org.apache.jackrabbit.oak.spi.commit.CompositeEditor.propertyAdded(CompositeEditor.java:83)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.propertyAdded(EditorDiff.java:82)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:395)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148)

at org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState.compareAgainstBaseState(ModifiedNodeState.java:416)

at org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:52)

at org.apache.jackrabbit.oak.spi.commit.EditorHook.processCommit(EditorHook.java:54)

at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:61)

at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:61)

at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch$InMemory.merge(DocumentNodeStoreBranch.java:497)

at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch.merge0(DocumentNodeStoreBranch.java:182)

at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch.merge(DocumentNodeStoreBranch.java:118)

at org.apache.jackrabbit.oak.plugins.document.DocumentRootBuilder.merge(DocumentRootBuilder.java:159)

at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.merge(DocumentNodeStore.java:1653)

at org.apache.jackrabbit.oak.core.MutableRoot.commit(MutableRoot.java:247)

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.commit(SessionDelegate.java:347)

at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:494)

... 18 common frames omitted

Looking for expects suggestions here...

Replies

Highlighted

kautuk_sahni

Community Manager

28-01-2018

You get this exception when 2 threads concurrently try to write to the same location. Please review your code to avoid race condition.

  • Avoid long running sessions and replace them by a number of short-living sessions. This is the way to go and in most cases the easiest solution to implement. This also avoids the problems coming with shared sessions.
  • Add code to call session.refresh(true) before you do your changes. This refreshes the session state to the HEAD state, exceptions are less likely then. If you run into a RepositoryException you should explicitly cleanup your transient space using session.refresh(false); then you’ll loose your changes, but the next session.save() will not fail for sure. This the path you should choose when you cannot create new sessions.

Joerg​ can you help here?

Highlighted

radhakrishnan72

29-01-2018

Hi Jörg Hoh,

                          thanks for asking this question. I have seen these two exceptions in different times based on understanding i have for last few months.

Thanks & Regards,

Radhakrishna.

Highlighted

smacdonald2008

29-01-2018

Looks like threads are trying to access the same thread - do you have a custom service attempting to manipulate the nodes?

Highlighted

radhakrishnan72

29-01-2018

Hi smacdonald2008,

                                   the processing and replication process is a custom process. Processing metadata takes first in the sequence and replication using replication API. Any asset has to go through these two steps. I have to set up "JCR write logging" to look into more details. I am waiting to get more load on the instance.

Thanks & Regards,

Radhakrishna.

Highlighted

radhakrishnan72

29-01-2018

Hi kautuksahni,

                          i have some of the doubts. Could you please clarify them so that i can best use them?

I use to get session from adapting it from resource resolver. Is it really required to immediately close current session after piece of work?

I am aware resolver closes it when resolver is closed.

Is it recommended to open and close  multiple sessions to process (seq of operations) one asset?

Is it recommended to call refresh on session every time as application process thousands of assets in a day?

Is it suggested to open and close resource resolver for each asset of operations? If yes, what is the cost of it and is it really recommended?

Thanks & Regards,

Radhakrishna.

Highlighted

Jörg_Hoh

Employee

30-01-2018

Hi,

the first rule of session and resource resolvers is: "You open it, you close it".

Adapting a session from a resourceresolver does not open a new session.

The second rule of sessions and resource resolvers is: "Do not utilize long-running sessions!" (the exception to this rule are sessions which are solely used for JCR Observation). Long-running sessions are sessions, which can be open potentially for days. A typical anti-pattern for this rule is to open a resource resolver in the activate() method of an OSGI service and close it on deactivate().

Think of JCR sessions or ResourceResolvers just like transactions. If you implement a serial process of steps, use a single session for it and use "session.save()" where it makes sense. Read [1] to learn about how much changes should be done before calling "session.save()".

Calling "session.refresh(true)" typically indicates problems in session handling, because then it is assumed, that multiple sessions act on the same content at the same time (which is causing problems in most cases).

HTH,

Jörg

[1] AEM transaction size or “do a save every 1000 nodes” | Things on a content management system