Anti-Pola OSIV
Alih-alih membiarkan lapisan bisnis memutuskan cara terbaik untuk mengambil semua pengaitan yang diperlukan oleh lapisan Tampilan, OSIV (Sesi Terbuka dalam Tampilan) memaksa Konteks Persistensi untuk tetap terbuka sehingga lapisan Tampilan dapat memicu inisialisasi Proxy, seperti yang diilustrasikan dengan diagram berikut.

- Itu
OpenSessionInViewFilter menyebut openSessionmetode yang mendasari SessionFactorydan memperoleh baru Session.
- Itu
Session terikat ke TransactionSynchronizationManager.
- Itu
OpenSessionInViewFilter menyebut doFilterdari javax.servlet.FilterChainreferensi objek dan permintaan itu diproses lebih lanjut
- Itu
DispatcherServlet disebut, dan rute permintaan HTTP ke mendasari PostController.
- Itu
PostController panggilan PostServiceuntuk mendapatkan daftar Postentitas.
- Itu
PostService membuka transaksi baru, dan HibernateTransactionManagermenggunakan kembali sama Sessionyang dibuka oleh OpenSessionInViewFilter.
- The
PostDAOmenjemput daftar Postentitas tanpa menginisialisasi setiap asosiasi malas.
- Itu
PostService melakukan transaksi yang mendasarinya, tetapi Sessiontidak tertutup karena dibuka secara eksternal.
- The
DispatcherServletdimulai rendering UI, yang, pada gilirannya, menavigasi asosiasi malas dan memicu inisialisasi mereka.
- The
OpenSessionInViewFilterdapat menutup Session, dan koneksi database yang mendasari dilepaskan juga.
Pada pandangan pertama, ini mungkin tidak terlihat seperti hal yang buruk untuk dilakukan, tetapi, setelah Anda melihatnya dari perspektif database, serangkaian kekurangan mulai menjadi lebih jelas.
Lapisan layanan membuka dan menutup transaksi database, tetapi setelah itu, tidak ada transaksi eksplisit yang terjadi. Karena alasan ini, setiap pernyataan tambahan yang dikeluarkan dari fase rendering UI dijalankan dalam mode komit otomatis. Komitmen otomatis memberi tekanan pada server database karena setiap pernyataan harus membuang log transaksi ke disk, sehingga menyebabkan banyak lalu lintas I / O di sisi database. Salah satu pengoptimalan akan menandaiConnection sebagai read-only yang akan memungkinkan server database untuk menghindari penulisan ke log transaksi.
Tidak ada lagi pemisahan masalah karena pernyataan dibuat oleh lapisan layanan dan proses rendering UI. Menulis pengujian integrasi yang menegaskan jumlah pernyataan yang dihasilkan melalui semua lapisan (web, layanan, DAO) saat aplikasi diterapkan di wadah web. Bahkan ketika menggunakan database dalam memori (misalnya HSQLDB) dan web server ringan (misalnya Jetty), pengujian integrasi ini akan lebih lambat untuk dijalankan daripada jika lapisan dipisahkan dan pengujian integrasi back-end menggunakan database, sedangkan pengujian integrasi pengujian integrasi front-end mengejek lapisan layanan sama sekali.
Lapisan UI terbatas untuk menavigasi asosiasi yang pada gilirannya dapat memicu masalah kueri N + 1 . Meskipun Hibernate menawarkan @BatchSizeuntuk mengambil pengaitan dalam kelompok, dan FetchMode.SUBSELECTuntuk mengatasi skenario ini, anotasi memengaruhi rencana pengambilan default, sehingga diterapkan ke setiap kasus penggunaan bisnis. Untuk alasan ini, kueri lapisan akses data jauh lebih cocok karena dapat disesuaikan dengan persyaratan pengambilan data kasus penggunaan saat ini.
Last but not least, koneksi database diadakan sepanjang fase rendering UI yang meningkatkan waktu sewa koneksi dan membatasi throughput transaksi secara keseluruhan karena kemacetan di pool koneksi database. Semakin banyak koneksi ditahan, semakin banyak permintaan bersamaan lainnya yang akan menunggu untuk mendapatkan koneksi dari pool.
Spring Boot dan OSIV
Sayangnya, OSIV (Sesi Terbuka dalam Tampilan) diaktifkan secara default di Spring Boot , dan OSIV benar - benar ide yang buruk dari perspektif kinerja dan skalabilitas .
Jadi, pastikan bahwa di application.propertiesfile konfigurasi, Anda memiliki entri berikut:
spring.jpa.open-in-view=false
Ini akan menonaktifkan OSIV sehingga Anda dapat menangani dengan LazyInitializationExceptioncara yang benar .
Dimulai dengan versi 2.0, Spring Boot mengeluarkan peringatan ketika OSIV diaktifkan secara default, sehingga Anda dapat menemukan masalah ini jauh sebelum itu mempengaruhi sistem produksi.
Untuk detail lebih lanjut tentang OSIV, lihat artikel ini .