2016-09-21 2 views
0

Я пытаюсь придумать рабочее решение, когда дело доходит до добавления контента к узлам JCR, выполняемым в разных экземплярах одного и того же кластера.Блокировка JCR в среде с несколькими кластерами

Было разъяснено here, что «когда несколько узлов кластера записываются в одни и те же узлы, эти узлы должны быть сначала заблокированы».

Что я сделал, но я все еще получает несвежие исключения элементов, как показано ниже:

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) 

Я также следовать предложенному подходу о том, как заблокировать узлы here (см 17.10 замков и операцию)

здесь приведена упрощенная версия моего кода, когда дело доходит до процедур блокировки.

session.getRootNode().addNode("one").addMixin("mix:lockable"); 
    session.save(); 
    session.getWorkspace().getLockManager().lock("/one", true, true, 5000, session.getUserID()); 
    session.save();// usually it explodes here 
    session.getNode("/one").addNode("two").addMixin("mix:lockable"); 
    session.save(); 
    session.getWorkspace().getLockManager().unlock("/one"); 

Обратите внимание, что это будет выполняться в двух разных случаях (clu в то же время.

Как вы можете видеть в моем коде выше, он взрывается после того, как я попытаюсь сохранить блокировку, только что добавленную к узлу, однако это рекомендация, указанная в ранее опубликованном link. Я понимаю, почему он взрывается, потому что два экземпляра пытались добавить блокировку на том же узле. Когда замок добавляются к узлу он изменяет узел, добавив два свойства (JCR: lockOwner и JCR: lockIsDeep), так что если экземпляра 1 добавленного замок затем экземпляра 2 добавленного замок и instance1 попытался сохранить, тогда вы получите устаревший элемент, потому что экземпляр 2 изменил узел, добавив к нему замок ... так как я мог бы предотвратить это?

Большое спасибо за вашу поддержку!

ответ

0

я как-то нашел эту тему и проверил ваш код, что вы здесь не так, что вы получение сеанса на основе поэтому ваши кластерные репозитории не имеют представления о блокировке, поскольку не применяются к кластерному узлу.

Что вы должны сделать вместо этого, чтобы сделать следующее:

session.getWorkspace().getLockManager().lock("/one", true, false, 5000, session.getUserID()); 

Более подробную информацию можно найти по адресу: https://wiki.apache.org/jackrabbit/Clustering#Concurrent_Write_Behavior Особенно в колонке ограничений.

0

Может быть, вы могли бы попробовать с node.refresh(false), чтобы заставить узел, чтобы обновить свой кэш и получить новые модификации

+0

Когда вы выполните обновление? перед сохранением или перед блокировкой? также в документации [здесь] (https://docs.adobe.com/content/docs/en/spec/jsr170/javadocs/jcr-2.0/javax/jcr/Item.html#refresh (boolean)) говорится, что все изменения будут очищены для текущего сеанса, если применяется обновление (false). Но я думаю, что моя проблема связана с изменениями, примененными другой сессией? – zalis

+0

Перед тем, как сохранить. Если узел уже изменен, он все равно будет непригодным. Но вы, возможно, правы, я неправильно понял, что обновление фактически просто «перезагружает» все ожидающие изменения в текущем ssession. Я никогда не использовал Jackrabbit в кластерной среде, чтобы быть честным – Nico

Смежные вопросы