Search code examples
javaxodus

jetbrains.exodus.ExodusException: Can't acquire environment lock after 0 ms


We are using Xodus on a Servlet container, and from time to time the application throws this error (which we don't know what is the cause)

jetbrains.exodus.ExodusException: Can't acquire environment lock after 0 ms.

 Lock owner info: 
null
    at jetbrains.exodus.log.Log.tryLock(Log.java:935)
    at jetbrains.exodus.log.Log.<init>(Log.java:91)
    at jetbrains.exodus.env.Environments.newLogInstance(Environments.java:137)
    at jetbrains.exodus.env.Environments.newLogInstance(Environments.java:115)
    at jetbrains.exodus.env.Environments.newLogInstance(Environments.java:104)
    at jetbrains.exodus.env.Environments.newInstance(Environments.java:49)
    at jetbrains.exodus.env.Environments.newInstance(Environments.java:39)

What could be causing this to happen?

Example Usage:

public void put(String instance, final String storeName, final String key, final String value) {
    final Environment env = Environments.newInstance(xodusRoot + instance);
    env.executeInTransaction(new TransactionalExecutable() {
        @Override
        public void execute(@NotNull final Transaction txn) {
            final Store store = env.openStore(storeName, StoreConfig.WITHOUT_DUPLICATES, txn);
            store.put(txn, StringBinding.stringToEntry(key), StringBinding.stringToEntry(value));
        }
    });
    env.close();
}

Where this put method is called from a Servlet endpoint, thus multiple concurrent clients of the server call this method.


Solution

  • BTW, it's very inefficient to open/close Environment on each request. It makes sense to keep environments open while they are updated. To limit the number of open environments, probably it's good to have a cache of open environments and to close those pushed out of the cache.