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 openSession
metode yang mendasari SessionFactory
dan memperoleh baru Session
.
- Itu
Session
terikat ke TransactionSynchronizationManager
.
- Itu
OpenSessionInViewFilter
menyebut doFilter
dari javax.servlet.FilterChain
referensi objek dan permintaan itu diproses lebih lanjut
- Itu
DispatcherServlet
disebut, dan rute permintaan HTTP ke mendasari PostController
.
- Itu
PostController
panggilan PostService
untuk mendapatkan daftar Post
entitas.
- Itu
PostService
membuka transaksi baru, dan HibernateTransactionManager
menggunakan kembali sama Session
yang dibuka oleh OpenSessionInViewFilter
.
- The
PostDAO
menjemput daftar Post
entitas tanpa menginisialisasi setiap asosiasi malas.
- Itu
PostService
melakukan transaksi yang mendasarinya, tetapi Session
tidak tertutup karena dibuka secara eksternal.
- The
DispatcherServlet
dimulai rendering UI, yang, pada gilirannya, menavigasi asosiasi malas dan memicu inisialisasi mereka.
- The
OpenSessionInViewFilter
dapat 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 @BatchSize
untuk mengambil pengaitan dalam kelompok, dan FetchMode.SUBSELECT
untuk 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.properties
file konfigurasi, Anda memiliki entri berikut:
spring.jpa.open-in-view=false
Ini akan menonaktifkan OSIV sehingga Anda dapat menangani dengan LazyInitializationException
cara 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 .