JDO: PersistenceManager - это синглтон? - PullRequest
3 голосов
/ 28 октября 2010

Только основы: я использую DataNucleus со встроенной базой данных DB4O.

Если я сделаю этот простой тест:

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

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

Я получаю исключение заблокированного файла:

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

Что говорит мне, что я не знаю, как PersistenceManager должен работать. Я думал, что просто вызываю PersistenceManagerFactory всякий раз, когда мне нужно PersistenceManager для запроса или сохранения данных, и я получаю что-то поточно-безопасное.

  • Нужно ли сделать PersistenceManager синглтон через всю мою приложение?
  • Как сделать несколько темы, выполнение запросов и обновления работают в JDO / DataNucleus?

Ответы [ 4 ]

2 голосов
/ 29 октября 2010

Между прочим, я вырвал DB4O и заглянул в NeoDatis (спасибо DN, что выполнил эту задачу за 5 минут), и каждый из полдюжины тестовых случаев, которые меня расстроили и подняли руки, волшебным образом сработал.Параллельные транзакции вели себя так, как я и предполагал, я мог внезапно сохранить коллекции сериализуемых объектов (отдельная, но одинаково неприятная проблема) и, по крайней мере, 4 других, которые были их производными.

Возможно, моя ошибка в неправильной настройкеDB4O (хотя у меня была ванильная установка, которую я только мог себе представить), но NeoDatis получил основные бонусные баллы в категории «Это просто работает».Обе установки встроены ванильно, оба создают файл, оба отвечают на JDO через DataNucleus.

Я не могу представить себе переключение обратно на DB4O после 3 дней ада, которые были стерты с 5-минутного счастья NeoDatis.:)

2 голосов
/ 28 октября 2010

Нужно ли мне сделать PersistenceManager единым целым во всем приложении?

Это зависит от вашего приложения. Если вы разрабатываете настольное приложение, вам, вероятно, нужен только один менеджер сохраняемости. Этот сохраняющий менеджер представляет состояние базы данных для вашего настольного приложения. Однако для других сценариев это не так. Например, в веб-приложении вы хотите изолировать запросы или сеансы друг от друга. Поэтому вы используете несколько PersistenceManager. Например, PersistenceManager для каждого запроса. Каждый PersistenceManager содержит состояние и транзакцию для текущего запроса.

То есть экземпляр PersistenceManager представляет собой единицу работы / транзакции.

2 голосов
/ 28 октября 2010
  • Вам не нужно создавать экземпляр синглтона.Вместо этого DataNucleus рекомендует использовать Persistence Manager Proxy .

Итак, следуя руководству, ваш код должен работать с этим изменением:

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

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

Второй экземпляр - это Proxy, ссылающийся на первый экземпляр PersistenceManager.

  • Чтобы сделать ваш поток PersistenceManager безопасным, вы должны установить свойство datanucleus.ConnectionFactory (или его псевдоним javax.jdo.option.Multithreaded) в вашем PersistenceManagerFactory .

Например, установить его программно:

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);
1 голос
/ 28 октября 2010

Как вы ожидаете, что db4o будет поддерживать одновременные запросы, когда вы работаете в «файловом» режиме? Казалось бы, режим сервера является обязательным условием

...