Управление сессиями NHibernate? - PullRequest
8 голосов
/ 19 июля 2009

Во-первых, позвольте мне дать краткое описание сценария. Я пишу простую игру, в которой почти вся работа выполняется на стороне сервера с тонким клиентом для доступа игроков. Игрок входит в систему или создает учетную запись, а затем может взаимодействовать с игрой, перемещаясь по сетке. Когда они входят в ячейку, они должны быть проинформированы о других игроках в этой ячейке, и аналогично, другие игроки в этой ячейке будут проинформированы о том, что этот игрок входит в нее. Есть много других взаимодействий и действий, которые могут иметь место, но не стоит вдаваться в подробности о них, поскольку это просто больше того же самого. Когда игрок выходит из системы, а затем снова входит в систему или если сервер выключается и возвращается в рабочее состояние, все игровое состояние должно сохраняться, хотя в случае сбоя сервера не имеет значения, потерял ли я около 10 минут изменений.

Я решил использовать NHibernate и базу данных SQLite, поэтому я много читал о NHibernate, следуя учебным пособиям и написание некоторых примеров приложений, и я полностью сбит с толку относительно того, как мне следует поступить об этом! *

У меня есть вопрос: как лучше всего управлять своими сессиями? Только из небольшого количества, которое я понимаю, все эти возможности выскакивают у меня:

  • Один сеанс, который всегда открыт, который используют все клиенты
  • Иметь один сеанс для каждого клиента, который подключается и периодически очищать его
  • Открывайте сеанс каждый раз, когда мне нужно использовать какие-либо из сохраняемых сущностей, и закрывайте его, как только обновление, вставка, удаление или запрос завершаются
  • Создайте сеанс для каждого клиента, но оставляйте его отключенным и подключайте его только тогда, когда мне нужно его использовать
  • То же, что и выше, но оставляйте его подключенным и отключайте его только после определенного периода бездействия
  • Держите сущности отделенными и присоединяйте их только каждые 10 минут, скажем, чтобы зафиксировать изменения

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

Еще один небольшой вопрос: как мне эффективно использовать транзакции? Это нормально для каждого отдельного изменения в его собственной транзакции, или это будет работать плохо, когда сотни клиентов пытаются изменить ячейки в сетке? Должен ли я попытаться выяснить, как объединить похожие обновления и поместить их в одну транзакцию, или это будет слишком сложно? Мне даже нужны транзакции для большей части?

Ответы [ 4 ]

10 голосов
/ 20 июля 2009

Я бы использовал сеанс на запрос к серверу и одну транзакцию на сеанс. Я бы не стал оптимизировать производительность до того, как приложение станет зрелым.

Ответ на ваши решения:

  • У вас всегда открыт один сеанс, который используют все клиенты: у вас возникнут проблемы с производительностью, поскольку сеанс не является потокобезопасным, и вам придется блокировать все вызовы сеанса.
  • Создайте отдельный сеанс для каждого подключающегося клиента и периодически очищайте его. У вас будут проблемы с производительностью, поскольку все данные, используемые клиентом, будут кэшироваться. Вы также увидите проблемы с устаревшими данными из кэша.
  • Открывайте сеанс каждый раз, когда мне нужно использовать какой-либо из сохраняемых объектов, и закрывайте его, как только обновление, вставка, удаление или запрос завершены: у вас не возникнет проблем с производительностью. Недостатком является возможный параллелизм или проблемы с повреждением данных, поскольку связанные SQL-операторы не выполняются в одной транзакции.
  • Создайте сеанс для каждого клиента, но оставляйте его отключенным и подключайте его только тогда, когда мне нужно его использовать: NHibernate уже имеет встроенное управление подключениями, и это уже очень оптимизировано.
  • То же, что и выше, но оставляйте его подключенным и отключайте его только после определенного периода бездействия: вызовет проблемы, поскольку количество подключений sql ограничено, а также ограничит количество пользователей вашего приложения.
  • Держите сущности отсоединенными и присоединяйте их только каждые 10 минут, скажем, для фиксации изменений: вызовет проблемы из-за устаревших данных в отсоединенных сущностях. Вам придется отслеживать изменения самостоятельно, что в итоге приведет к появлению фрагмента кода, похожего на сам сеанс.

Теперь было бы бесполезно вдаваться в подробности, потому что я бы просто повторил руководства / учебники / книги. Когда вы используете сеанс для каждого запроса, у вас, вероятно, не будет проблем в 99% приложения, которое вы описываете (и, возможно, не совсем). Сеанс - это легкий не поточнобезопасный класс, чтобы жить очень недолго. Если вы хотите точно знать, как работает сеанс / подключение / кэширование / управление транзакциями, я рекомендую сначала прочитать руководство, а затем задать несколько более подробных вопросов по неясным вопросам.

1 голос
/ 20 июля 2009

Прочитайте 'ISessionFactory' на этой странице документации NHibernate. ISession s должны быть однопоточными (то есть не потокобезопасными), что, вероятно, означает, что вы не должны делиться ими между пользователями. ISessionFactory должно быть создано вашим приложением один раз, а ISession должно быть создано для каждой единицы работы. Помните, что создание ISession не обязательно приводит к открытию соединения с базой данных. Это зависит от того, как настроена стратегия пула соединений вашего SessionFactory.

Вы также можете посмотреть документацию Hibernate по Сессия и транзакция .

0 голосов
/ 20 июля 2009

Прочтите Советы NHibernate с ASP.NET , здесь есть несколько очень полезных советов для начала. Как уже упоминалось, будьте очень осторожны с ISession, поскольку он НЕ является потокобезопасным, поэтому просто имейте это в виду.

Если вам требуется что-то более сложное, взгляните на NHibernate.Burrow contrib contrib. В нем говорится что-то вроде «настоящая сила, которую обеспечивает Берроу, заключается в том, что разговор Берроу может охватывать несколько HTTP-запросов».

0 голосов
/ 20 июля 2009

Я бы хотел сохранить все в памяти и либо вносить изменения в журнал, либо делать периодические автономные снимки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...