Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Multithreaded environment getting exceptions

Avatar

Former Community Member

Hi,

We are running some load tests and solving issues that we are getting on the way but the issue with concurrency seems to be bothering me. How can we get around these problems?

I am not too much in favor of putting locks but can think about it.

Some of the exception traces are below:

16.10.2014 19:55:17.776 *WARN* [127.0.0.1 [1413442511753] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumers/l: failed to restore transient state
16.10.2014 19:55:17.777 *ERROR* [127.0.0.1 [1413442511753] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] kkk.register.UserCQSync RepositoryException Exception for user javax.jcr.InvalidItemStateException: property /home/groups/g/gp-consumers/rep:members: the property cannot be saved because it has been modified externally.
    at org.apache.jackrabbit.core.PropertyImpl.makePersistent(PropertyImpl.java:161)
    at org.apache.jackrabbit.core.ItemSaveOperation.persistTransientItems(ItemSaveOperation.java:849)
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:243)
    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 kkk.register.UserCQSync.loginAndCreateUserNodes(UserCQSync.java:128)
    at kkk.register.UserRegistrationServiceImpl.createUser(UserRegistrationServiceImpl.java:114)

 

And Some more:

 

 org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV//jcr:createdBy: failed to restore transient state

16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/sdfsd: failed to restore transient state
16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/wat: failed to restore transient state
16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/sdfsdf: failed to restore transient state
16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/sdfsd: failed to restore transient state
16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/jcr:created: failed to restore transient state
16.10.2014 19:55:17.877 *WARN* [127.0.0.1 [1413442511804] PUT kkk/kkk/user.desktop.v1.json HTTP/1.1] org.apache.jackrabbit.core.ItemSaveOperation /consumerskkk/LYf8PyYcCTXRN6SORV/jcr:primaryType: 

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

that's just standard transactional behaviour :-) You are not allowed to change the same items in 2 sessions in parallel, and there's no implicit ordering when this problem is detected; but the servlet just returns the raw exception back to you. If you need to deal with such situations (e.g it will happen during standard operation and is suppossed to work), you probably need to handle this situation, either by implementing your own servlet (which just implements retries or a higher-level locking based on the path), or you deal with it in your browser application (javascript).
 

kind regards,
Jörg

View solution in original post

3 Replies

Avatar

Correct answer by
Employee Advisor

Hi,

that's just standard transactional behaviour :-) You are not allowed to change the same items in 2 sessions in parallel, and there's no implicit ordering when this problem is detected; but the servlet just returns the raw exception back to you. If you need to deal with such situations (e.g it will happen during standard operation and is suppossed to work), you probably need to handle this situation, either by implementing your own servlet (which just implements retries or a higher-level locking based on the path), or you deal with it in your browser application (javascript).
 

kind regards,
Jörg

Avatar

Former Community Member

Jörg Hoh wrote...

Hi,

that's just standard transactional behaviour :-) You are not allowed to change the same items in 2 sessions in parallel, and there's no implicit ordering when this problem is detected; but the servlet just returns the raw exception back to you. If you need to deal with such situations (e.g it will happen during standard operation and is suppossed to work), you probably need to handle this situation, either by implementing your own servlet (which just implements retries or a higher-level locking based on the path), or you deal with it in your browser application (javascript).
 

kind regards,
Jörg

 

Hi Jorg,

Thanks for your reply. I am stress testing the system and basically, i am opening an admin session as i need to do group and user related operations. All this happens within a method and the variables have all got a local scope (and they are obviously not thread safe) . After i am done creating users and adding them to groups,i need to further create few other nodes which are user related and finally i save the session. All this done within a method which further calls other methods to complete the task. 

In case i receive this generic exception, i can rollback the transaction but stress testing is throwing a lot of these issues and client won't accept a lot of people being shown error screens in case of these issues.

I am not particularly sure of what you meant by (which just implements retries or a higher-level locking based on the path).

Thanks.

Avatar

Employee Advisor

Hi,

If this is happening in your code, you can just implement a retry in case you get such an exception. Your approach looks good.

But the question is, if you see such behaviour also in your daily operations; that means, do you endusers create the same user again and again (as it seems to be the case in your stress test)? If you see this behaviour also in a case when you want to add hundreds of distinct users/groups/... the problem might be different. Because then you're hitting a design aspect of Jackrabbit2: When you add a new childnode, the parent is modified as well (as all nodes hold a list of their child nodes). This could be the source of your problem. And for this I am not aware of a good solution; maybe you can serialize all these requests and put them into a queue to avoid this exception.

I am not sure if this is still the case with AEM 6.0 and Oak (tarMK or MongoMK).

kind regards,
Jörg