db4o - безопасность потоков, встроенный сервер, транзакции ... общие вопросы - PullRequest
1 голос
/ 10 октября 2011

Я работаю над интеграцией db4o в свой проект, и у меня есть несколько вопросов. Я прочитал руководство и попробовал несколько примеров, но я все еще не уверен, правильно ли я все понял. Пожалуйста, ответьте да / нет (или другими ответами, если есть вопросы, требующие этого: -))

1.) Использование ObjectContainer в качестве Singleton в приложении не рекомендуется, потому что, если разные транзакции работают с одним и тем же объектом, могут возникнуть конфликты.

2.) Поэтому для одновременных транзакций рекомендуется использовать встроенный сервер.

3.) При использовании встроенного сервера (локально) вы можете открывать (и закрывать) столько клиентов, сколько хотите, которые имеют свои собственные транзакции и кеш ссылок, чтобы они могли работать с одними и теми же объектами. НО - это все еще не безопасно для потоков, потому что два клиента могут работать с одним и тем же объектом, один клиент может изменить его, а другой не обновит.

4.) Поэтому - даже если вы работаете с разными клиентами, вам необходимо убедиться, что объекты, с которыми работают клиенты, всегда актуальны

5.) Вы можете убедиться в этом с помощью обратных вызовов или явного обновления. но использование обратных вызовов может означать большой сетевой трафик, а явное обновление сложно, потому что вам действительно нужно знать, когда обновлять какой объект - так что бы вы порекомендовали? и когда вы обновите объекты явно?

6.) Поскольку я пытаюсь написать DAO для db4o, я бы реализовал методы для открытия и закрытия сервера и открытия и закрытия клиентов. Я думаю, что сервер открыт только один раз в приложении, правильно? (Один сервер на приложение?)

7.) Вы бы порекомендовали ленивую инициализацию? так что только первый раз сервер необходим, он инициализируется.

8.) Вы бы открывали нового клиента для каждой транзакции?

9.) Если я работаю с несколькими транзакциями, но они не могут накладывать друг на друга, могу ли я использовать один ObjectContainer для всего проекта?

спасибо, что ответили: -)

1 Ответ

2 голосов
/ 10 октября 2011
  1. Зависит от приложения. Да, каждый контейнер имеет свой собственный кэш транзакций и ссылок, поэтому объекты являются общими. В настольном или мобильном приложении, которое делает только одно, это может быть желаемой моделью. В веб-приложении, в котором одновременно происходит несколько вещей, редко бывает подходящей моделью.

  2. Да. Вы можете открыть новый контейнер сеанса с помощью container.ext().openSession()

  3. db4o имеет 'read commit' изоляцию между объектными контейнерами / транзакциями. Контейнер читает только зафиксированные состояния из других транзакций. Но, как вы заметили, контейнер может видеть устаревший объект, потому что он использовал свою локальную кэшированную версию объекта. Вы ничего не можете сделать.

  4. Да. db4o не поддерживает вас в этом сценарии.

  5. Хм, мероприятие с освежающими напитками и прочим, нет никакой гарантии, что вы получите 100% согласованное представление ваших данных. Вы не можете достичь «сериализованного» уровня изоляции . Модель консистенции db4o просто не поддерживает это, когда задействованы несколько транзакций. Если ваши расы редки, то вы можете просто «игнорировать» проблему. Предполагается, что во многих случаях легче попытаться разобраться / жить / принять тот факт, что db4o не имеет более сильного уровня изоляции. Такие вещи, как «освежить» и «освежить по событию» только уменьшают шансы на такие условия гонки, но не могут полностью их избежать. Когда вам действительно требуется 100% корректность, вам нужна база данных, которая поддерживает «сериализованную» изоляцию.

  6. Да, обычно у вас запущен экземпляр db4o, а затем несколько клиентов или контейнеров сеансов.

  7. Я бы не стал выполнять ленивую инициализацию, если бы в этом не было необходимости. В любом случае, когда вам нужна база данных, просто запустите ее. Но в любом случае, это действительно зависит от вашего приложения.

  8. Также зависит от вашего приложения. Например, в веб-приложении я бы использовал новый контейнер сессии для каждой веб-сессии. В любом случае, каждый раз, когда вам нужно «чистое» состояние, вы должны использовать новый контейнер объектов. Вы не должны разделять контейнер объектов между различными единицами работы. И не делите контейнер объектов между потоками, если у вас нет синхронизации поверх него.

  9. В одном контейнере объекта может быть только одна транзакция. Когда вам нужно более одной транзакции одновременно, вам все равно нужно несколько контейнеров. Если у вас есть разные задачи, которые выполняются одна за другой, вы можете использовать один контейнер и одну и ту же транзакцию.

...