У чому полягає користь session.flush () у сплячому режимі


110

Коли ми оновлюємо запис, ми можемо використовувати session.flush()зі сплячим режимом. У чому потреба flush()?

Відповіді:


138

Промивання сеансу змушує Зимувати синхронізувати стан пам'яті Sessionз базою даних (тобто записувати зміни в базу даних). За замовчуванням Hibernate автоматично сформує зміни:

  • перед виконанням запитів
  • коли здійснена транзакція

Дозволяючи явно розмити, Sessionдає більш точний контроль, який може знадобитися за певних обставин (щоб отримати ідентифікатор, присвоїти розмір сесії, ...).


8
Зверніть увагу, що ця відповідь описує DEFAULT поведінку в сплячому режимі: поведінку змиву можна змінити за допомогою параметра режиму змиву. Деталі наведені у docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/… (версія 3.5).
SteveT

1
Я знайшов документ, де сказано саме те, що ви говорите, але у мене виникає питання, що пріоритет означає, припустимо, 1) У мене є клас, де я зберігаю об'єкт за допомогою коду, id = session.save(obj);і транзакція здійснюється в наступному рядку, але Obj не отримує збереження до БД, чому? 2) Я врятував obj, використовуючи session.save(obj);команду, і під час повернення використовував. return obj.getprimaryID();У цьому випадку obj зберігається в БД. То чому така поведінка відбувається?
Amogh

74

Як справедливо сказано у вищезазначених відповідях, закликаючи flush()ми змушуємо сплячий виконувати команди SQL на базі даних. Але розумійте, що зміни ще не "здійснені". Отож, виконуючи флеш та перед тим, як зробити фіксацію, якщо ви звертаєтесь до БД безпосередньо (скажімо, із запиту SQL) та перевіряєте модифіковані рядки, ви НЕ побачите змін.

Це те саме, що відкрити 2 сеанси команд SQL. І зміни, зроблені за 1 сеанс, не видно для інших, поки їх не буде здійснено.


12
Ну - зміни можна трохи помітити. Наприклад, невипущений рядок може створити блокування на вставленому, але невідомій рядку і затримати цей же рядок від вставки іншим сеансом, поки транзакція не буде здійснена або відкатана. Тож це не зовсім непомітно.
rghome

2
Я займався серфінгом в Інтернеті, і ця відповідь, нарешті, змусила мене це зрозуміти. Дякую.
Сіддхартха

в чому полягає користь введення .flush () у цикл for, тоді, якщо commit () робить флеш в кінці?
Ейльдоса

@Kaushik Lele Який сенс флеш (), якщо дані не видно після флеш? Чи можете ви детальніше зупинитися на деяких кращих випадках використання, коли це стане в нагоді?
java_geek

28

Я знаю лише, що коли ми зателефонуємо, session.flush()наші заяви виконуються в базі даних, але не виконуються.

Припустимо, що ми не викликаємо flush()метод на об’єкт сеансу, і якщо ми викличемо метод комісії, він внутрішньо виконає роботу з виконанням операторів на базі даних, а потім здзяйсненням.

commit=flush+commit (у разі функціональності)

Таким чином, я роблю висновок, що коли ми викликаємо метод flush () на об'єкт Session, він не отримує фіксації, а потрапляє в базу даних і виконує запит і отримує відкат також.

Для фіксації ми використовуємо commit () на об'єкті транзакції.


Чи можете ви дати детальну інформацію про те, що потрібно для промивання?
java_geek

14

Промивання сеансу отримує дані, які зараз перебувають на сесії, синхронізовані з тим, що є в базі даних.

Більше на веб-сайті зі сплячки:

flush()корисно, оскільки немає абсолютно жодних гарантій щодо того, коли сесія виконує дзвінки JDBC, лише порядок, у якому вони виконуються - за винятком використання flush().


Чи можете ви надати сценарій, коли користувач повинен турбуватися про послідовність? Використання сплячого режиму - зробити речі, пов’язані з БД, прозорими для користувачів. Коли ми робимо "фіксацію", промивання відбувається автоматично. Який сценарій, коли ви будете робити флеш, але не виконувати?
Каушик Леле

1
@KaushikLele ви можете звернутися на це питання stackoverflow.com/questions/37382872 / ...
GMsoF

10

Ви можете використовувати, flushщоб змусити обмеження перевірки реалізовуватися та виявлятися у відомому місці, а не тоді, коли транзакція здійснюється. Можливо, це commitназивається неявно за допомогою якоїсь логіки рамки, через декларативну логіку, контейнер або шаблон. У цьому випадку будь-який викинутий виняток може бути важко зловити і обробити (це може бути занадто великим у коді).

Наприклад, якщо у вас save()новий об’єкт EmailAddress, у якого є унікальне обмеження на адресу, ви не отримаєте помилку, поки не зробите.

Виклик flush()змушує вставити рядок, кидаючи виняток, якщо є дублікат.

Однак після виключення вам доведеться відмовити сеанс.


4

Я просто хотів би об'єднати всі відповіді, наведені вище, а також пов'язати метод Flush () з Session.save (), щоб надати більше значення

Hibernate save () може бути використаний для збереження об'єкта до бази даних. Ми можемо використовувати цей метод поза трансакцією, тому мені не подобається цей метод збереження даних. Якщо ми використовуємо це без транзакцій, і ми каскадуємо між сутностями, тоді зберігається лише первинний об'єкт, якщо ми не очистимо сеанс.

flush (): змушує сеанс розмиватися. Він використовується для синхронізації даних сесії з базою даних.

Коли ви викликаєте session.flush (), оператори виконуються в базі даних, але вони не здійснюються. Якщо ви не зателефонували session.flush () і якщо ви зателефонували session.commit (), метод внутрішньої віддачі () виконує оператор і виконує компіляцію.

Отже, виконувати () = змивати + виконувати. Тож session.flush () просто виконує висловлювання в базі даних (але не здійснює комісії), а висловлювання вже НЕ ПАМ'ЯТЬСЯ. Це просто змушує сеанс розмитися.

Кілька важливих моментів:

Ми повинні уникати збереження зовнішньої межі транзакцій, інакше відображені об'єкти не будуть збережені, викликаючи невідповідність даних. Дуже нормально забути пропустити сеанс, оскільки це не кидає жодного винятку чи попередження. За замовчуванням Hibernate автоматично сформує зміни: перед деякими виконанням запитів, коли трансакція буде здійснена. Дозволяє явно розмивати сеанс, надає більш точний контроль, який може знадобитися в деяких обставинах (для отримання ідентифікатора, щоб контролювати розмір сесії. )


3

flush() Метод викликає Hibernate промивати сесію. Ви можете налаштувати Hibernate для використання режиму промивання для сеансу за допомогою setFlushMode()методу. Щоб отримати режим флеш для поточного сеансу, ви можете скористатися getFlushMode()методом. Щоб перевірити, чи брудний сеанс, ви можете скористатися isDirty()методом. За замовчуванням Hibernate управляє промиванням сеансів.

Як зазначено в документації:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

Промивання

Промивання - це процес синхронізації стану постійного контексту з базовою базою даних. The EntityManagerand Hibernate відкриває Sessionнабір методів, за допомогою яких розробник програми може змінити стійкий стан сутності.

Контекст стійкості виконує функцію кеша транзакцій, що записується, чергуючи будь-які зміни стану сутності. Як і будь-який кеш, що записується, зміни спочатку застосовуються в пам’яті та синхронізуються з базою даних протягом поточного часу. Нарівні операція приймає кожна зміна стану особи і переводить його в INSERT, UPDATEабо DELETEзаяву.

Стратегія промивання задається flushMode поточного запущеного сплячого сеансу. Хоча JPA визначає лише дві стратегії промивання ( AUTOі COMMIT), Hibernate має набагато ширший спектр типів промивання:

  • ALWAYS: Змиває сеанс перед кожним запитом;
  • AUTO: Це режим за замовчуванням, і він змиває сесію лише за потреби;
  • COMMIT: Сесія намагається затримати флеш до тих пір, поки не буде здійснена поточна трансакція, хоча вона також може закінчитися передчасно;
  • MANUAL: Промивання сеансу делеговано програмі, яка повинна Session.flush()чітко зателефонувати , щоб застосувати постійні зміни контексту.

За замовчуванням Hibernate використовує AUTOрежим промивання, який запускає флеш за таких обставин:

  • до здійснення транзакції;
  • перед виконанням запиту JPQL / HQL, який перекривається з діями об'єкта в черзі;
  • перед виконанням будь-якого нативного запиту SQL, який не має зареєстрованої синхронізації.

1

Виклик EntityManager#flushмає побічні ефекти . Її зручно використовувати для типів об'єктів із згенерованими значеннями ідентифікаторів (значення послідовності): такий ідентифікатор доступний лише при синхронізації з базовим стійким шаром. Якщо цей ідентифікатор потрібен до завершення поточної транзакції (наприклад, для ведення журналу реєстрації), потрібно промити сеанс.


0

За допомогою цього методу ви викликаєте процес промивання. Цей процес синхронізує стан вашої бази даних зі станом сеансу шляхом виявлення змін стану та виконання відповідних операторів SQL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.