Issue with concurrent POST requests with Jersey RE

2019-09-02 02:56发布

问题:

I have Jersery Rest service and i am using Neo4j Embedded Database to serve requests with data.

Now when i make concurrent GET requests it works fine.

But when i make concurrent POST requests It gives Following Exception :

Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Component 'org.neo4j.kernel.StoreLockerLifecycleAdapter@62f1ca5e' was successfully initialized, but failed to start. Please see attached cause exception.
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:504)
    at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:115)
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:296)
    ... 42 more
Caused by: org.neo4j.kernel.StoreLockException: Could not create lock file
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:85)
    at org.neo4j.kernel.StoreLockerLifecycleAdapter.start(StoreLockerLifecycleAdapter.java:40)
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:498)

I know the problem is if there is already instance of neo4j running we can't access the same with another thread.

Solution would be Neo4j HA

But as i dont have enough time to configure Neo4j HA cluster, can anyone please suggest me on How can i make POST request to be single threaded (means no concurrent threads accessing Neo4j at the same time).

Any link or tutorial.

Edit

I am starting neo4j like this:

GraphDatabaseService graphdb = new GraphDatabaseFactory().newEmbeddedDatabase("D:/GraphDB");'

and in finally block i am doing

graphdb.shutdown();

回答1:

Not sure how GET requests are working in this case, perhaps someone from Neo4j team could best provide for an explanation. I'm assuming that you are initializing and shutting graphdb with each request. Also, I haven't been in touch with Java lately, my suggestion may not be accurate.

The way I think I would deal with this is by not initializing and shutting graphdb with each request. The reason being that Neo4j locks on a graph database directory and won't allow a new thread to re-initialize an embedded instance on the same directory (read thread-safe). Instead, I'd rather use a singleton class which exposed graphdb and re-use it as a shared object in the JVM. graphdb.shutdown() could occur in a shutdown hook for your Jersey service (graphdb shuts down only when the service goes down). This aligns with what Pangea suggested, ServletContextListener is a good place to do this. However, implementation may vary with Jersey.

Finally, I'd be polite with people who are trying to help out by editing your question, commenting and asking for context around your problem. :)



回答2:

too late to answer this but again if anyone is facing the same issue ,this is how i fixed it. Maintain a singleton class. i.e,

      GraphDatabaseService graphdb=null;
      if(graphdb.isAvailable()&& graphdb!=null)
       {
            return graphdb;
       }
       else
        {
           graphdb = new GraphDatabaseFactory().newEmbeddedDatabase("D:/GraphDB");
         return graphdb;
        }