Dear BaseX experts,
I'm wondering if anybody can see something that I'm doing wrong. I would expect it to be possible to add documents from multiple threads. Am I wrong about that??
When I set two of my datasets saving documents to BaseX 7.9 at the same time, I get this exception:
$ basexserver BaseX 7.9 [Server] Server was started (port: 1984) Exception in thread "Thread-2295" java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryRelease(ReentrantReadWriteLock.java:374) at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260) at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.unlock(ReentrantReadWriteLock.java:1131) at org.basex.core.DBLocking.release(DBLocking.java:219) at org.basex.core.Context.unregister(Context.java:249) at org.basex.core.Command.execute(Command.java:104) at org.basex.core.Command.execute(Command.java:117) at org.basex.server.ClientListener.execute(ClientListener.java:384) at org.basex.server.ClientListener.add(ClientListener.java:355) at org.basex.server.ClientListener.run(ClientListener.java:100)
All I am doing is making concurrent calls in two parallel sessions:
session = new ClientSession(...) session.execute(new Open(database)) session.execute(new Set("autoflush", "false")) session.add([path string], [document-bytes]) // a zillion times session.execute(new Flush())
During the execution of the parallel add commands, it crashes.
The relevant code:
def withSession[T](block: ClientSession => T): T = { val session = new ClientSession(host, port, user, pass) try { block(session) } finally { session.close() } }
def withDbSession[T](database: String)(block: ClientSession => T): T = { withSession { session => session.execute(new Open(database)) session.execute(new Set("autoflush", "false")) val result = block(session) session.execute(new Flush()) result } }
then:
withDbSession { session => // many calls to session.add(...) }