Добрый день. Возможно задаю глупый вопрос, но поиски в интернете так и не дали мне подходящий ответ.
Собственно проблема такая. Запускаем два клиентских приложения, оба они при запуске вычитывают список Entity (некоторая сущность). Далее меняем в одном приложении имя у сущности и сохраняем в базу. Если после этого во втором приложении нажать кнопочку обновить, то ничего не изменится, имя у сущности останется старым. А вот если в первом приложении добавить новую сущность, то при обновлении во втором приложении она появится.
Хочется чтобы при обновлении получались актуальные данные из базы. Можно перед обновлением делать Clear у ISession или создавать другую ISession, либо вообще использовать IStatelessSession, но подходящие ли это решения, не приведут ли они к другим проблемам, что посоветуете делать?
Вот например таким тестом можно выразить проблему (тест не срабатывает):
Здравствуйте, DK-Warder, Вы писали:
DW>Хочется чтобы при обновлении получались актуальные данные из базы. Можно перед обновлением делать Clear у ISession или создавать другую ISession, либо вообще использовать IStatelessSession, но подходящие ли это решения, не приведут ли они к другим проблемам, что посоветуете делать?
В случае когда базу правят несколько приложений — следует использовать короткоживущие сессии (одна сессия на одну транзакцию БД) либо stateless сессии.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, DK-Warder, Вы писали:
DW>>Хочется чтобы при обновлении получались актуальные данные из базы. Можно перед обновлением делать Clear у ISession или создавать другую ISession, либо вообще использовать IStatelessSession, но подходящие ли это решения, не приведут ли они к другим проблемам, что посоветуете делать?
Z>В случае когда базу правят несколько приложений — следует использовать короткоживущие сессии (одна сессия на одну транзакцию БД) либо stateless сессии.
Здравствуйте, DK-Warder, Вы писали:
DW>Добрый день. Возможно задаю глупый вопрос, но поиски в интернете так и не дали мне подходящий ответ. DW>Собственно проблема такая. Запускаем два клиентских приложения, оба они при запуске вычитывают список Entity (некоторая сущность). Далее меняем в одном приложении имя у сущности и сохраняем в базу. Если после этого во втором приложении нажать кнопочку обновить, то ничего не изменится, имя у сущности останется старым. А вот если в первом приложении добавить новую сущность, то при обновлении во втором приложении она появится. DW>Хочется чтобы при обновлении получались актуальные данные из базы. Можно перед обновлением делать Clear у ISession или создавать другую ISession, либо вообще использовать IStatelessSession, но подходящие ли это решения, не приведут ли они к другим проблемам, что посоветуете делать?
DW>Вот например таким тестом можно выразить проблему (тест не срабатывает): DW>
Это нормальное поведение — NHibernate может отследить изменения только в направление код->БД, а не наоборот.
Вывод:
— не бойтесь создавать и убивать сессии — сами по себе они достаточно легковесны;
— не используйте одну сессию для нескольких транзакций в конкуррентной среде (когда могут существовать одновременно несколько сессий).
Еще одно маленькое замечание: для NHibernate версии > 2.0 всегда используйте явные транзакции в коде, даже на чтение.
Здравствуйте, meowth, Вы писали:
M>Еще одно маленькое замечание: для NHibernate версии > 2.0 всегда используйте явные транзакции в коде, даже на чтение.
Здравствуйте, Ахмед, Вы писали:
А>Здравствуйте, meowth, Вы писали:
M>>Еще одно маленькое замечание: для NHibernate версии > 2.0 всегда используйте явные транзакции в коде, даже на чтение.
А>Интересно, можно узнать — почему?
Можно
Формальный ответ — потому что так сказали разработчики =)
Фактический — по следующим соображениям:
а) При некоторых конфигурациях версионирования данных (имеется в виду модель оптимистических блокировок) будут некорректно работать версии.
б) Ручное управление транзакциями — это зло, и обычно от него отказываются в пользу автоматического/декларативного управления — TransactionScope, например (лично я использую Spring.Transactions). В момент перехода вы будете очень удивлены результатом, когда все начнет работать по-другому, потому что менеджер транзакций теперь явно рулит транзакциями сессии Хибернейта :D
в) Чтение данных вне явной транзакции НЕ использует кэш второго уровня. Нет, это сейчас вы его не включили, а потом подключите и будете долго ломать голову, почему он не работает, и переписывать каждое обращение к ISession.
г) Такой способ вынуждает писать правильно: делать выборку внутри сессии (транзакции) и сразу диспозить ее — в противном случае вы нахватаете косяков при обновлении коллекций и lazy-load'е.