2016-08-10 6 views
0

Я получаю следующее исключение в среде с одним окном cq5.javax.jcr.InvalidItemStateException: Предмет не может быть сохранен

javax.jcr.InvalidItemStateException: Item cannot be saved 
because node property has been modified externally 

более подробно исключение:

Caused by: javax.jcr.InvalidItemStateException: Unable to update a stale item: item.save() 
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:262) 
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216) 
    at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91) 
    at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:329) 
    at org.apache.jackrabbit.core.session.SessionSaveOperation.perform(SessionSaveOperation.java:65) 
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216) 
    at org.apache.jackrabbit.core.SessionImpl.perform(SessionImpl.java:361) 
    at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:812) 
    at com.day.crx.core.CRXSessionImpl.save(CRXSessionImpl.java:142) 
    at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.commit(JcrResourceProvider.java:511) 
    ... 215 more 
Caused by: org.apache.jackrabbit.core.state.StaleItemStateException: 3bec1cb7-9276-4bed-a24e-0f41bb3cf5b7/{}ssn has been modified externally 
    at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:679) 
    at org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1507) 
    at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1537) 
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:400) 
    at org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354) 
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:375) 
    at org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:275) 
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:258) 

Вот пример кода:

adminResourceResolver = resourceResolverFactory 
       .getAdministrativeResourceResolver(null); 
Resource fundPageResource = adminResourceResolver.getResource(page 
       .getPath() + "/jcr:content"); 
ModifiableValueMap homePageResourceProperties = fundPageResource 
       .adaptTo(ModifiableValueMap.class); 
homePageResourceProperties.put("ssn",(person.getSsn()); 

adminResourceResolver.commit(); 

Любые идеи? Можно было бы использовать несколько потоков, обращаясь к этому коду, как несколько авторов на нескольких страницах, вызывающих этот код из авторского компонента.

Спасибо, Шри

+1

Есть ли у вас код для публикации? –

+0

@A_Arnold Пожалуйста, смотрите образец кода, извлеченный из кода. – Sri

ответ

3

Это ошибка ваших см часто в CQ5.5 (и уменьшается с каждой версией вверх). Основной причиной этой проблемы является то, что несколько процессов/сервисов изменяют один и тот же ресурс примерно в один и тот же промежуток времени (обычно с использованием разных сеансов, иногда даже с разными пользователями).

Небольшой пример, чтобы продемонстрировать, возможно. В сеансах A и B есть ссылка на Resource X. Session A изменяет некоторые свойства на X, сохраняет и фиксирует и уничтожается. Все идет гладко. В сеансе B по-прежнему имеется снимок ситуации до внесенных изменений, сеанс B вносит изменения, и все кажется хорошо, пока он пытается сохранить. На этом этапе сеанс B обнаруживает, что он не может выполнить свои изменения, потому что он не имеет последнего состояния узла. Он обнаружил, что некоторые другие сеансы внесли изменения в один и тот же узел. По существу текущее состояние узла конфликтует с модификациями, которые выполнял сеанс A, и выбрасывает исключение ItemStale. Причиной этого исключения является то, что API не знает, что вы хотите сохранить изменения, внесенные A, сохранить изменения, сделанные в текущем сеансе, и отказаться от изменений, сделанных A, или слить их.

Эта ошибка часто возникает при длительных сеансах работы и комбинациях рабочих процессов/слушателей. Поэтому рекомендация состоит в том, чтобы как можно короче проводить сессии, чтобы как можно больше предотвратить подобные конфликты.

Один из способов борьбы с этим вызовом - вызвать session.refresh (keepChangesBoolean) перед вызовом .save(). Это указывает текущему сеансу проверить обновления, сделанные другими сеансами, и обработать его в соответствии с логическим флагом, который вы отправляете. Это, однако, не является гарантией, поскольку все еще возможно, что между вашим обновлением и вашим вызовом сохранения, еще один сеанс сделал то же самое. Это лишь уменьшает вероятность возникновения этого исключения. Другой способ справиться с этим - повторить попытку с нуля.

+0

Спасибо @ 3xil3, это имеет смысл. Я знаю, как работать с транзакциями в обычном webapp, а не в приложении JCR. – Sri