views:

33

answers:

4

Just the basics: I'm using DataNucleus backed with an embedded DB4O database.

If I do this simple test:

    PersistenceManager pm1 = persistenceManagerFactory.getPersistenceManager();
    PersistenceManager pm2 = persistenceManagerFactory.getPersistenceManager();

    pm1.makePersistent(t1);
    pm2.makePersistent(t2);

I get a file locked exception:

com.db4o.ext.DatabaseFileLockedException: C:\<path>\primary_datastore.data

Which tells me I don't know how the PersistenceManager is supposed to work. I thought I just called PersistenceManagerFactory whenever I needed a PersistenceManager to query or persist data and I would get something thread safe.

  • Do I need to make PersistenceManager a singleton across my entire application?
  • How do multiple threads, performing queries and updates work in JDO/DataNucleus?
+1  A: 

So, following the guide, your code should work with this change:

PersistenceManager pm1 = persistenceManagerFactory.getPersistenceManager();
PersistenceManager pm2 = persistenceManagerFactory.getPersistenceManagerProxy();

pm1.makePersistent(t1);
pm2.makePersistent(t2);

The second instance is a Proxy referring the first PersistenceManager instantiated.

For instance, setting it programatically:

Properties properties = new Properties();
properties.setProperty("javax.jdo.PersistenceManagerFactoryClass",
                "org.datanucleus.jdo.JDOPersistenceManagerFactory");
//configure connection, etc...
properties.setProperty("javax.jdo.option.Multithreaded", "true");
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(properties);
Tomas Narros
But if I run concurrent requests to the same PersistenceManager object I also run into problems (I think, but I wiped those test cases). Perhaps The answer from DataNucleus is on track? Thoughts?
David Parks
+1  A: 

Do I need to make PersistenceManager a singleton across my entire application?

It depends on you application. If you developing a desktop-application you probably only need only one persistence manager. This persistence-manager represent the state of the database for you desktop-app. However for other scenarios this isn't the case. For example in web application you want to isolate the requests or sessions from each other. Therefore you use multiple PersistenceManager. For example a PersistenceManager per request. Each PersistenceManager hold the state and transaction for the current request.

So a PersistenceManager-instance represents a unit work / transaction.

Gamlor
Thanks, indeed this is a webapp, and to me it seemed like a separate PersistenceManager per request seemed logical.
David Parks
Ok. Then you probably need to use the db4o embedded server mode. I guess you can configure this in DataNucleus:http://www.datanucleus.org/products/accessplatform/db4o/support.html
Gamlor
+1  A: 

How exactly do you expect db4o to support concurrent requests when you operate in "file" mode ? Would have thought server mode is a prerequisite

DataNucleus
I'm not sure, I just wanted an embedded server. It seemed file mode was the way to go for an embedded server, otherwise I just expected it to work like a regular database. Can you clarify? Is file mode not the way to go if I just want an embedded server for a web application? The way I read the DN docs it said that it runs in Server mode (I assume this is operating as a remote server opening listening ports, clearly not embedded, client, again, not embedded, and file, which seemed like the only other logical choice).
David Parks
+1  A: 

Incidentally, I ripped out DB4O and popped in NeoDatis (thank you DN for making that a 5 min task) and each of a half dozen test cases that had me baffled and throwing up my hands magically worked. Concurrent transactions behaved as I assumed they should, I could suddenly persist collections of serializable objects (a separate but equally frustrating issue), and at least 4 others that were derivatives of these.

Perhaps my fault for mis-configuring DB4O (though I had as vanilla an install as I could possibly contemplate), but NeoDatis got major bonus points in the "It just works" category. Both vanilla embedded installs, both create a file, both respond to JDO via DataNucleus.

I can't imagine switching back to DB4O after 3 days of hell that were erased with 5 minutes of NeoDatis bliss. :)

David Parks
So, the error was not at the use of the PersistenceManager, but in some kind of file lock mishandled by the DB4O database driver? Congrats for finding it, and +1 for sharing your solution.
Tomas Narros
I probably bungled something, lots of people use DB4O, but I had the most vanilla install I could do using DataNucleus using the File store method (which seemed logical from the DN docs). But DB4O (at least with DataNucleus) gets a low score on the "It just works" scale, whereas NeoDatis gets a very high "It just works" score.
David Parks