You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A call to commit() after defining a new database schema may hang indefinitely after if another transaction is open (in the same PMF).
package org.zoodb.test;
import org.zoodb.jdo.ZooJdoHelper;
import org.zoodb.jdo.ZooJdoProperties;
import org.zoodb.tools.ZooHelper;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
public class DummyTest {
public static void main(String[] args) {
String dbName = "fail.zoo";
if (ZooHelper.dbExists(dbName)) {
ZooHelper.removeDb(dbName);
}
ZooHelper.createDb(dbName);
ZooJdoProperties props = new ZooJdoProperties("fail.zoo");
props.setMultiThreaded(true);
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props);
PersistenceManager pmMain = pmf.getPersistenceManager();
pmMain.currentTransaction().begin();
// ZooJdoHelper.schema(pmMain).addClass(Apple.class); // <-- Workaround
pmMain.currentTransaction().commit();
PersistenceManager pmWorker = pmf.getPersistenceManager();
Runnable r = new Runnable() {
@Override
public void run() {
pmWorker.currentTransaction().begin();
pmWorker.makePersistent(new Apple());
pmWorker.currentTransaction().commit();
pmMain.currentTransaction().begin();
System.out.print("begin last commit in thread... "); // is reached
pmMain.currentTransaction().commit();
System.out.println("done!"); // problem: is not reached
}
};
Thread t = new Thread(r, "Some external thread");
t.start();
}
}
and
package org.zoodb.test;
import org.zoodb.api.impl.ZooPC;
public class Apple extends ZooPC {
}
Analysis
Workaround:
Define the schema before opening other transactions.
Background
This happens because the second transaction is (implicitly) creating a schema for Apple in the database. Multithreading should work fine in normal use cases, but schema definition is different. In effect, a schema definition causes all PMF session to reset, however the reset is blocked because the first PM (pmMain) is still active.
Fix?
Causing all transactions to reset after schema change is a kind of pessimistic fail-early approach. Alternatively, Transaction reset could be delayed until a transaction actually tries to read or write to an outdated schema, I am not sure whether that would necessarily be better. It may also impact performance.
TODO
Either the problem should be fixed (=no blocking behavior), or there should be at least a proper error message what is happening.
Another user reported that making the lock reentrant fixes the problem. This is not the preferred solution because the server is designed such that reentrant locks should not be necessary. In the server design, entering a lock twice points to a problem in the server that should be fixed.
The text was updated successfully, but these errors were encountered:
The "hang" has only been fixed when setting DiskAccessOneFile.allowReadConcurrency(true);, however this is generally not recommended (and not an official feature!).
A call to
commit()
after defining a new database schema may hang indefinitely after if another transaction is open (in the same PMF).and
Analysis
Workaround:
Define the schema before opening other transactions.
Background
This happens because the second transaction is (implicitly) creating a schema for Apple in the database. Multithreading should work fine in normal use cases, but schema definition is different. In effect, a schema definition causes all PMF session to reset, however the reset is blocked because the first PM (pmMain) is still active.
Fix?
Causing all transactions to reset after schema change is a kind of pessimistic fail-early approach. Alternatively, Transaction reset could be delayed until a transaction actually tries to read or write to an outdated schema, I am not sure whether that would necessarily be better. It may also impact performance.
TODO
Either the problem should be fixed (=no blocking behavior), or there should be at least a proper error message what is happening.
Another user reported that making the lock reentrant fixes the problem. This is not the preferred solution because the server is designed such that reentrant locks should not be necessary. In the server design, entering a lock twice points to a problem in the server that should be fixed.
The text was updated successfully, but these errors were encountered: