powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate
7 сообщений из 7, страница 1 из 1
Hibernate
    #32840436
^ozzy^
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть следующий код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
        Session session1 =  new  Configuration().configure().buildSessionFactory().openSession();
        Session session2 =  new  Configuration().configure().buildSessionFactory().openSession();

        Transaction tx1 = session1.beginTransaction();
        Transaction tx2 = session2.beginTransaction();

        News n1 = (News) session1.iterate("from News where id=36").next();
        News n2 = (News) session2.iterate(("from News where id=36")).next();

        n1.setSummary("x");
        session1.update(n1);
        session1.flush();

        n2.setSummary(n2.getSummary() + "y");
        session2.update(n2);
        session2.flush();

        tx1.commit();
        tx2.commit();


Нужно каким-либо образом разрулить ситуацию так, чтобы в базе в поле summary записалось "xy" ..
n2 изменилось после изменения news в tx1.

Каким образом это можно сделать ? Что читать, куда копать? Или, возможно, кто-то уже сталквался с такой проблемой.

Фактически нужно научиться разруливать конфилкты между сессими на предмет перекрестных записей в таблицу(т.е. чтобы целостность не нарушилась).
...
Рейтинг: 0 / 0
Hibernate
    #32840818
fynda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
        Session session1 =  new  Configuration().configure().buildSessionFactory().openSession();
        Session session2 =  new  Configuration().configure().buildSessionFactory().openSession();

        Transaction tx1 = session1.beginTransaction();

        News n1 = (News) session1.iterate("from News where id=36").next();
        News n2 = (News) session2.iterate(("from News where id=36")).next();

        n1.setSummary("x");
        session1.update(n1);
        session1.flush();
        
         //-------------------------------------------------
        tx1.commit();
        Transaction tx2 = session2.beginTransaction();
         //-------------------------------------------------

        n2.setSummary(n2.getSummary() + "y");
        session2.update(n2);
        session2.flush();

        tx1.commit();
        tx2.commit();

>Что читать, куда копать?

IMHO: transaction isolation level
...
Рейтинг: 0 / 0
Hibernate
    #32841028
^ozzy^
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Примером кода поделитесь ?
...
Рейтинг: 0 / 0
Hibernate
    #32841324
fynda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
^ozzy^Примером кода поделитесь ?

Это не код, это надо в доке к базе данных смотреть или в книжке. В вашем примере с довольно большой вероятностью дело в том, что вторая транзакция не видит изменений первой, пока первая не сделает коммит. Попросту потому, что первая может сделать и rollback, и что она выберет - до ее завершения не ясно.

То есть "правильная" последовательность должна быть такой:
- стартует транзакция 1
- читает базу
- делает изменения
- делает коммит
- стартует транзакция 2
- читает базу
- делает изменения
- делает коммит

... а в таком варианте

- стартует транзакция 1
- тр 1 читает базу
- тр 1 делает изменения
- стартует транзакция 2
- тр 2 читает базу
- тр 2 делает изменения
- делает коммит тр 1
- делает коммит тр 2

...скорее всего будет конфликт (в лучшем случае) или запишется неверное значение, в зависимости от настроек сервера.
...
Рейтинг: 0 / 0
Hibernate
    #32841585
^ozzy^
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда вопрос на засыпку. Как средствами MySQL произвести такую проверку ?

Хотя, быть может, кому-то придет более правильное решение проблемы в голову.
Ситуация в конкретном случае слудующая:

для доступа к базе данных используется Hibernate.

есть n юзеров.

При Login'e каждого юзера открывается новая сессия, и соответственно, транзакция.
Вот здесь и возможна проблема нарушения целостности.


Я вижу несколько вариантов решения(связанных с изменением логики).
1. Создать одну сессию и подсовывать ее все юзерам(здесь мы сталкиваемся с двумя проблемами. Во-первых, сессия может постоянно обрыватся по time-out.
Во-вторых, сессия может очень сильно разрастись в плане использумой памяти).

2. Разграничить типы запросов на те, которые могут нарушить целостность и на те, которые нет(например, log). Первые commit'ить сразу, а для вторых использовать транзакции (для увеличения эффективности).
Здесь проблема в том, что реализовывать и поддерживать такой код будет крайне неудобно.

Есть какие-либо еще варианты решения данной проблемы?

/PS: решения, фактически, на любом уровне(база данных, java-приложения).
...
Рейтинг: 0 / 0
Hibernate
    #32846938
Dimitry Mardiyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Первое что приходит на ум. Возможно поможет optimistic locks (скажем by version)..

То есть при втором update - Hibernate прокинет exception, который можно корректно отхендлить (в смысле зарефрешить объект)...

Подробности тут:
http://www.hibernate.ru/docs/ru/html/transactions.html

Второе - поиграться с уровнями транзакционной изоляции.. Но тут многое зависит от меппинга, и скорее всего не получится, ибо в данном случае считывание объекта n2 пройдет до внесения изменений в объект n1... Но вот если

Код: plaintext
News n2 = (News) session2.iterate(("from News where id=36")).next();

Будет стоять после

Код: plaintext
session1.flush();

Грязное считывание может помочь.

А в чем основная проблема-то? Если суть в том, чтобы не перекрывать конкурентные изменения - тогда однозначно метод номер 1 (optimistic locks).

Если нет - тогда хотелось бы подробнее узнать о проблеме.
...
Рейтинг: 0 / 0
Hibernate
    #32846939
Dimitry Mardiyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
^ozzy^
Я вижу несколько вариантов решения(связанных с изменением логики).
1. Создать одну сессию и подсовывать ее все юзерам(здесь мы сталкиваемся с двумя проблемами. Во-первых, сессия может постоянно обрыватся по time-out.
Во-вторых, сессия может очень сильно разрастись в плане использумой памяти).


Не стоит, сессия не thread-safe и так делать не надо ибо потом хлопот не оберешся.

По предназначению Hibernate Session - короткоживущий объект и используется только в single-thread и для одного unit-of-work. За счет чего обеспечивается высокий перформанс. Разделение его между threads приведет к magic things (в народе именуемой гонкой за ресурсами). К тому же придется синхронизировать все POJO объекты - перформанс упадет очень сильно.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]