Антидіаграма OSIV
Замість того, щоб дозволити бізнес-шару вирішувати, як найкраще отримати всі асоціації, необхідні шару «Перегляд», OSIV (Open Session in View) змушує контент контексту залишатися відкритим, щоб шар View міг спровокувати ініціалізацію проксі, як показано на малюнку за наступною схемою.
OpenSessionInViewFilter
Викликає openSession
метод базового активу SessionFactory
і отримує новий Session
.
Session
Пов'язаний з TransactionSynchronizationManager
.
OpenSessionInViewFilter
Називає doFilter
в якості javax.servlet.FilterChain
посилання об'єкта і запит додатково обробляється
DispatcherServlet
Називається, і він направляє запит HTTP , щоб лежачий в основі PostController
.
- У
PostController
дзвінки на , PostService
щоб отримати список Post
сутностей.
PostService
Відкриває нову транзакцію, і HibernateTransactionManager
повторно той же , Session
що був відкритий OpenSessionInViewFilter
.
PostDAO
Отримує список Post
осіб без ініціалізації будь ледачою асоціації.
PostService
Здійснює основну угоду, але Session
не закритий , так як він був відкритий зовні.
- У
DispatcherServlet
запуску рендеринга інтерфейсу, який, в свою чергу, переходить ледачі асоціації і викликає їх ініціалізації.
- Can
OpenSessionInViewFilter
може закрити Session
, і базове з'єднання бази даних також вивільнено.
На перший погляд, це може не виглядати як жахлива річ, але, коли ви переглядаєте це з точки зору бази даних, ряд недоліків починає ставати більш очевидним.
Сервісний рівень відкривається та закриває транзакцію бази даних, але після цього явної транзакції не відбувається. З цієї причини кожне додаткове повідомлення, видане на етапі візуалізації користувальницького інтерфейсу, виконується в режимі автоматичної фіксації. Автоматичне фіксація чинить тиск на сервер бази даних, оскільки кожне висловлення повинно передати журнал транзакцій на диск, тому спричиняючи багато трафіку вводу / виводу на стороні бази даних. Однією з оптимізацій було б позначити Connection
як лише для читання, що дозволить серверу баз даних уникати запису в журнал транзакцій.
Більше проблем не існує, тому що заяви створюються як службовим рівнем, так і процесом надання інтерфейсу користувача. Для написання тестів на інтеграцію, що підтверджують кількість генерованих висловлювань, потрібно пройти всі шари (веб, сервіс, DAO) під час розгортання програми на веб-контейнері. Навіть при використанні бази даних в пам'яті (наприклад, HSQLDB) та легкого веб-сервера (наприклад, Jetty), ці інтеграційні тести виконуватимуться повільніше, ніж якби шари були розділені і тести інтеграції заднього рівня використовували базу даних, тоді як фронтальні тести інтеграції взагалі глузували з сервісного рівня.
Шар інтерфейсу обмежується навігаційними асоціаціями, які, в свою чергу, можуть викликати проблеми запитів N + 1 . Незважаючи на те, що програма "Hibernate" пропонує @BatchSize
асоціації для отримання пакетів у пакетних групах і FetchMode.SUBSELECT
щоб впоратися з цим сценарієм, примітки впливають на план вибору за замовчуванням, тому вони застосовуються до кожного випадку використання бізнесу. З цієї причини запит рівня доступу до даних набагато підходить, оскільки він може бути адаптований до поточних вимог використання даних щодо використання випадку.
І останнє, але не менш важливе, підключення до бази даних проводиться протягом усієї фази візуалізації інтерфейсу, що збільшує час оренди з'єднання та обмежує загальну пропускну здатність транзакцій через перевантаженість пулу підключення до бази даних. Чим більше з'єднання проведено, тим більше інших одночасних запитів буде чекати, щоб отримати з'єднання з пулу.
Весняне завантаження та OSIV
На жаль, OSIV (Open Session in View) включено за замовчуванням у Spring Boot , а OSIV - це дійсно погана ідея з точки зору продуктивності та масштабованості .
Отже, переконайтеся, що у application.properties
файлі конфігурації є такий запис:
spring.jpa.open-in-view=false
Це відключить OSIV, щоб ви могли правильно впоратисяLazyInitializationException
.
Починаючи з версії 2.0, Spring Boot видає попередження, коли OSIV увімкнено за замовчуванням, тому ви можете виявити цю проблему задовго до того, як вона вплине на виробничу систему.
Щоб отримати докладнішу інформацію про OSIV, перегляньте цю статтю .