|
|
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey KuznetsovТеперь понял. Тогда остается еще такое решение: делаете маркерное поле и выборки делаете с учетом маркерного поля, что бы другие коннекты не тащили "логически незакомиченные" данные. Что бы упростить написание запросов, таблицы можно вьюхами обернуть, которые автоматом отфильтруют данные. Я один раз похожее решение использовал: флажок "IsDeleted" который приходилось постоянно иметь ввиду при написании запросов, муторно, но другого выхода думаю нету.Ваше решение не подходит по нескольким причинам: 1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 09:54:21 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, +1 В субд (не орм) работает уровень изоляции READ_COMMITED для этого. Это можно сделать руками, но лучше бы это УЖЕ было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 10:00:37 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:24:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovsvenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции. да, конечно так можно решить. Это метод "READ_COMMITED - вручную". Но блин, это нужно проводить через весь функционал Хибера. Это нужно проводить через всю Модель. Т.е. то что контролирует БД, нужно протягивать по всем уровням. Когда тут налево и направо все кричат о преимуществах инжекции, декларативных и Великом помощнике Спринге. Не факт, что данный метод проще чем перед транзакцией кидать объекты в сессию HTTP и потом обратно мержить их. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:50:06 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
возможно проще iBatis взять, если у хибера такие заморочки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:51:08 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovsvenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции.Ну это все равно велосипед, так как у автора есть апп. сервер и именно он должен хранить состояние сесии пользователя, а не СУБД. Ваш подход подошел бы в двухзвенке или каких-то особых случаях трехзвенки (например - кластер с сохранением состояния в БД). Какие минусы: 1) Лишние операции с СУБД, лишний сетевой траффик 2) Проблемы с поддержанием целостности информации. Например, пользователь удаляет какую-то строку, потом пытается сохранить изменения, но в этот момент апп. сервер падает (вырубили электричество, а ИБП замкнуло ). В итоге, после рестарта сервака в СУБД имеется запись об удалении, которая уже не связана ни с какой сессией и вообще ХЗ что с ней делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:54:35 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovфлаг IsDeleted я привел для своего случая, помню по своим проектам, и проектам 1С, что требование в ТЗ "сущность не удаляется, а как-бы удаляется" порождает такие проблемы для разработчика и архитектуры... Если там конечно, достаточно связей и логики между ними. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:56:05 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, ну да, только пока непонятно, как делать запросы к не сброшенным в БД данным или до flush(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:58:54 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
заказчику: Всегда лучше сперва попробовать использовать в приложении традиционные ACID-свойства (длинные с вкладками). Но если вы готовы пожертвовать некоторой частью согласованности БД и целостности данных ради производительности, стоит рассмотреть стратегию высокой производительности (короткие транзакции без вкладок) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 13:04:12 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
вообщем поразмыслив я пришел к выводу, что модель(не держим сессию, во всех закладках только читаем данные, все изменения храним в структуре памяти и передаем через сессию или еще как и накатываем в конце. а выборки фильтруем в ручную) которую предложил svenom. тоже имеет минусы: 1. это необходимо все писать руками) 2. необходимо также вести очередь изменений, так как порядок важен при итоговом сохранении 3. и главное: необходимо фильтровать выборки руками причем тут тоже проблемы: а) фильтрация на удаленные элементы, запросили 20 на страницу, выяснили что 2 из них удалены, удалили их из результата, в итоге отдаем на страницу 18. Пользователю не понятно почему так, почему не 20....а подгрузить еще 2 недостающих это и лишний запрос к бд, и нарушение логики, ведь они попадут и на следующую страницу(запрос следующих 20) при пэйджинге. Как быть в этом случаи???? б) добавление элементов которые в памяти в выборки по условию тоже сложный процесс, разработчики вкладок должны будут бегать по коллекциям и сверять подходят ли добавленные элементы под их условия или нет. что совсем не прозрачно и накладывает дополнительные усилия на разработку закладок, чего заказчик хотел избежать. Вообщем совсем жизнь не сладка......к тому же вопрос из пункта 3.а, остается открытым, как быть в такой ситуации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:20:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
LeonidvView не должен работать с СУБД. Между ними еще есть слой DAO и Service и не забываем про модель. Т.е. ваш пользователь в своих вкладках работает с моделью, при необходимости подгружая данные из СУБД. Вы реализуете все операции типа delete/insert в памяти (можно в сервисах, если сделать цикл жизни не singleton, а как у сессии), а далее при запросе от пользователя просто сохраняете все изменения в БД. Вкладки работают только с сервисами и моделями, что и позволяет нам утвреждать, что они ничего друг от друге не знают. Вы наверно не совсем верно поняли, да по задумке вкладки работают только с сервисами, но они должны получать/знать изменения которые были сделаны на предыдущих вкладках. Посмотрите мое предыдущее сообщение(на 1 выше этого) и увидите какие возникают проблемы и вопросы в данном подходе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:27:49 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery3. и главное: необходимо фильтровать выборки руками причем тут тоже проблемы: а) фильтрация на удаленные элементы, запросили 20 на страницу, выяснили что 2 из них удалены, удалили их из результата, в итоге отдаем на страницу 18. Пользователю не понятно почему так, почему не 20....а подгрузить еще 2 недостающих это и лишний запрос к бд, и нарушение логики, ведь они попадут и на следующую страницу(запрос следующих 20) при пэйджинге. Как быть в этом случаи???? уж запрос на выборку с параметрами limit и offset для разработчика вкладок должен быть прозрачным наверняка и то, что мы в результат не включили 2 удаленных элемента его не касается, это должно быть не им сделано, а "мной" то есть в обертки на сервис или еще как. Есть идеи по этому поводу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:34:39 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, Ну тогда реализуйте эту логику на уровне БД, как Alexey Kuznetsov предлагал выше. Придумываете некую таблицу (или таблицы - одну для изменений, другую - для удалений, третью - для созданных записей), в которой будут храниться изменения, например CREATE TABLE ... ( id, session_id, table_name, ... ) Тут ключевое поле - session_id - идентификатор сессии. Дальше фикачите кучу всяких вьюшек, которые будут отображать данные с учетом изменений пользователя. Далее навешиваете на эти вьюхи триггеры, которые будут не только сохранять изменения в релаьные таблицы, но и будут чистить вспомогательные. Далее создаете какую-либо джобу, которая будет периодически подчищать "мусор" во вспомогательных таблицах после нештатных ситуаций (напр., вырубили электричество, как я говорил выше). Далее навешиваете на сессию пользователя листенер, что бы при закрытии сессии, чистились записи, относящиеся к этой сессии, во вспомогательных таблицах. Минусы - лишний траффик в БД до коммита пользователя, много дополнительного кода на уровне СУБД. Плюсы - автоматом решаются проблемы с пейджингом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:01:02 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Мне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:16:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию.В вашем решении абсолютно не важно будет использован Хибер или нет. Если да - просто делаем flush(), а потом откатываем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:29:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. хм.....интересный вариант, мне только от хибера отказываться нельзя, таково требование не рушимое, но сама идея интересна, к примеру на хибере 1) есть "главная сессия" она открывается при первом запросе 2) все удаления, добавления проводятся через "главную сессию" 3) при выборках "главная" сессия клонируется(если такое возможно, я не знаю) , открывается транзакция в клонированной сесии, сбрасывается(флаш) выполняется выборка, транзакция откатывается и клонированная сессия закрывается 4) в итоге при завершаещем коммите либо сбрасываем(флэш) "главную" сессию либо закрываем ее Кто что думает? возможен ли такой вариант? если возможен в чем его минусы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:30:33 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
или даже не нужно клонировать сессию, а просто делать флаш перед выборкой и откатывать в конце? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:31:52 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyЙуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. хм.....интересный вариант, мне только от хибера отказываться нельзя, таково требование не рушимое, но сама идея интересна, к примеру на хибере 1) есть "главная сессия" она открывается при первом запросе 2) все удаления, добавления проводятся через "главную сессию" 3) при выборках "главная" сессия клонируется(если такое возможно, я не знаю) , открывается транзакция в клонированной сесии, сбрасывается(флаш) выполняется выборка, транзакция откатывается и клонированная сессия закрывается 4) в итоге при завершаещем коммите либо сбрасываем(флэш) "главную" сессию либо закрываем ее Кто что думает? возможен ли такой вариант? если возможен в чем его минусы?Не прокетит. Еще раз повторяю - сессия Хибера не прденазначена для решения этой задачи, ее нельзя сюда пихать в принципе. Йуный джавистЪ предлагает немного модифицированное мое решение: создаем все ту же структуру в Http сессии. На каждой операции чтения происходит следующее - все изменения сначала сбрасываются в базу (не важно как - хотите через JDBC, хотите через Хибер - пофиг), после этого происходит считывание необходимой информации, а потом откат транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:34:59 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, а можете объяснить почему не прокатит??? ведь сессия хибера и так в себе содержит подобные структуры что вы предлагаете сделать руками(то есть хранит что надо удалить что обновить и т.д.) почему если клонировать сессию то не получится? хотя возможно ее нельзя клонировать, этого я не знаю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:46:24 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, В вашем решении абсолютно не важно будет использован Хибер или нет. Согласен, если использовать session per request, как вы и советовали. Если держать hibernate сессию между запросами, как пытался slippery, то гибернейт тут никак не приспособить. Йуный джавистЪ предлагает немного модифицированное мое решение Да, так и есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:50:50 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪsvenom, В вашем решении абсолютно не важно будет использован Хибер или нет. Согласен, если использовать session per request, как вы и советовали. Если держать hibernate сессию между запросами, как пытался slippery, то гибернейт тут никак не приспособить. Йуный джавистЪ предлагает немного модифицированное мое решение Да, так и есть. кстати как я понимаю в таком решении нельзя использовать декларативное управление транзакциями от спринга @Transactional над методами сервисов, ибо как я понял спринг принудительно закрывает(коммитит) транзакцию открытую или открывает и закрывает новую. И еще а можно как-нибудь отключить в рантайме этот механизм, сделать так чтоб обращения к сервисам из определенных мест проходило в не спринговского перехватчика ну или что-то еще в этом духе, ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:01:26 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
просто проект в который я уже пришел разрабатывался по методу: не полностью продуманная архитектура в самом начале, а быстро быстро накидывать функционал для показов, а дальше уже по мере появления решать задачи, и так я пришел в готовый проект в котором сессия сейчас открывается по запросу, декларативное управления транзакциями через спринг. и вот мне выдана такая задача, так что тут еще момент с интеграцией решения в проект существует. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:03:32 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Мысль клонировать сессию хибернейта интересная, но я в целом не советую вам это делать. Экономия усилий не такая большая, а перспектива развлечься с хибернейтом вполне реальная. Кроме того, подумайте, разберется ли с этим ваш последователь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:08:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysvenom, а можете объяснить почему не прокатит??? ведь сессия хибера и так в себе содержит подобные структуры что вы предлагаете сделать руками(то есть хранит что надо удалить что обновить и т.д.) почему если клонировать сессию то не получится? хотя возможно ее нельзя клонировать, этого я не знаю1. Сессия Хибера не содержит реализации метода clone(). 2) Ее нельзя сериализовать-десериализовать, так как в ней присутствуют несериализуемые зависимые объекты (транзакция, коннекшн и т.д..) А когда вы делаете flush() вы изменяете состояние сессии и нельзя потом заставить сделать ее этот же flush() еще раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:13:04 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМысль клонировать сессию хибернейта интересная, но я в целом не советую вам это делать. Экономия усилий не такая большая, а перспектива развлечься с хибернейтом вполне реальная. Кроме того, подумайте, разберется ли с этим ваш последователь. спасибо за ответы, думал что-то наподобие этого использовать: public <T> T clone(T obj){ T theClone = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream(baos.toByteArray()) ); theClone = (T)ois.readObject(); но и правда возникает вопрос с объектами внутри сессии которые имеют лайзи поля. Просто хотелось бы по минимому писать код, чем его будет меньше тем и легче разобраться?) а про предыдущие вопросы насчет отключения в рантайме декларативного управления спрингом транзакций, ну или изменения чтоб он не во всех случаях автокомит делал, что нибудь знаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:14:22 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=37615074&tid=2132841]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
49ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
76ms |
get tp. blocked users: |
2ms |
| others: | 324ms |
| total: | 500ms |

| 0 / 0 |
