Saya kesulitan memahami saat hibernasi mencapai cache tingkat kedua dan kapan hal itu membuat cache tidak valid.
Inilah yang saat ini saya pahami:
- Cache tingkat kedua menyimpan entitas antar sesi, cakupannya adalah SessionFactory
- Anda harus memberi tahu entitas mana yang akan disimpan dalam cache, tidak ada entitas yang akan di-cache secara default
- Cache kueri menyimpan hasil kueri di cache.
Yang tidak saya mengerti adalah
- Kapan hibernasi mencapai cache ini?
- Katakanlah saya telah menyiapkan cache tingkat kedua tetapi bukan cache kueri. Saya ingin menyimpan cache pelanggan saya, ada 50000 dari mereka. Dengan cara apa saya bisa mengambil pelanggan dari cache?
- Saya berasumsi saya bisa mendapatkannya dengan id dari cache. Itu akan mudah tetapi juga tidak layak untuk disimpan dalam cache. Tetapi bagaimana jika saya ingin melakukan perhitungan dengan semua pelanggan saya. Misalkan saya ingin menampilkan daftar pelanggan, lalu bagaimana saya mengaksesnya?
- Bagaimana cara mendapatkan semua pelanggan saya jika cache kueri dinonaktifkan?
- Apa yang akan terjadi jika seseorang memperbarui salah satu pelanggan?
- Akankah pelanggan itu menjadi tidak valid dalam cache atau apakah semua pelanggan akan dibatalkan?
Atau apakah saya berpikir cache salah? Apa penggunaan yang lebih tepat dari cache tingkat kedua dalam kasus itu? Dokumentasi hibernate sama sekali tidak jelas bagaimana cache bekerja pada kenyataannya. Hanya ada instruksi tentang cara menyiapkannya.
Pembaruan: Jadi saya telah memahami bahwa cache tingkat kedua (tanpa cache kueri) akan baik untuk memuat data dengan id. Misalnya saya memiliki objek pengguna yang ingin saya periksa izinnya di setiap permintaan dalam aplikasi web. Apakah ini kasus yang baik untuk mengurangi akses database dengan menyimpan pengguna dalam cache tingkat kedua? Seperti saya akan menyimpan id pengguna dalam sesi atau di mana pun dan ketika saya perlu memeriksa izin, saya akan memuat pengguna dengan id itu dan memeriksa izin.
Jawaban:
Pertama-tama, mari kita bicara tentang cache level proses (atau cache level 2 sebagaimana mereka menyebutnya dalam mode Hibernate). Untuk membuatnya berhasil, Anda harus melakukannya
Anda memberi tahu penyedia cache berapa banyak objek yang harus disimpan dan kapan / mengapa objek tersebut harus dibatalkan. Jadi katakanlah Anda memiliki entitas Buku dan Penulis, setiap kali Anda mendapatkannya dari DB, hanya yang tidak ada dalam cache yang akan dipilih dari DB sebenarnya. Ini meningkatkan kinerja secara signifikan. Berguna bila:
Jadi kapan cache berfungsi?
session.get()
atausession.load()
objek yang sebelumnya dipilih dan berada di cache. Cache adalah penyimpanan di mana ID adalah kuncinya dan propertinya adalah nilainya. Jadi hanya ketika ada kemungkinan untuk mencari berdasarkan ID Anda bisa menghilangkan memukul DB.Tapi itu tidak berhasil jika:
from Authors where name = :name
maka Anda tidak menekan cache.where id = ?
).fetch="join"
, ini berarti bahwa untuk memuat asosiasi, gabungan akan digunakan di mana saja, bukan pernyataan pilih yang terpisah. Cache tingkat proses bekerja pada objek anak-anak hanya jikafetch="select"
digunakan.fetch="select"
tetapi kemudian di HQL Anda menggunakan gabungan untuk memilih asosiasi - gabungan tersebut akan segera dikeluarkan dan mereka akan menimpa apa pun yang Anda tentukan di hbm.xml atau penjelasan.Sekarang, tentang Query Cache. Anda harus mencatat bahwa ini bukan cache terpisah, ini adalah tambahan untuk cache tingkat proses. Misalkan Anda memiliki entitas Negara. Ini statis, jadi Anda tahu bahwa setiap kali akan ada hasil yang sama yang ditetapkan saat Anda mengatakannya
from Country
. Ini adalah kandidat yang tepat untuk cache kueri, ini akan menyimpan daftar ID itu sendiri dan ketika Anda memilih semua negara di lain waktu, ini akan mengembalikan daftar ini ke cache tingkat proses dan yang terakhir, pada gilirannya, akan mengembalikan objek untuk setiap ID karena objek ini sudah disimpan di cache tingkat ke-2. Cache kueri tidak valid setiap kali apa pun yang terkait dengan entitas berubah. Jadi katakanlah Anda mengonfigurasifrom Authors
untuk ditempatkan ke dalam Cache Kueri. Ini tidak akan efektif karena Penulis sering berubah.sumber
Pada kenyataannya, memiliki cache terdistribusi nilai-kunci sangatlah berguna - itulah yang dimaksud dengan memcache, dan ini mendukung facebook, twitter, dan banyak lagi. Tetapi jika Anda tidak memiliki pencarian berdasarkan id, maka itu tidak akan berguna.
sumber
Terlambat ke pesta tetapi ingin menjawab secara sistematis pertanyaan ini yang banyak ditanyakan oleh pengembang.
Mengajukan pertanyaan Anda satu per satu di sini adalah jawaban saya.
A. Cache Tingkat Pertama dikaitkan dengan objek Sesi . The Second Level Cache dikaitkan dengan objek Session Factory . Jika objek tidak ditemukan di tingkat pertama, maka tingkat kedua diperiksa.
A. Jawabannya ada di update Anda. Juga cache kueri menyimpan hanya daftar ID dari objek dan Objek tersebut dengan ID mereka disimpan dalam cache tingkat kedua yang sama . Jadi, jika Anda mengaktifkan cache kueri, Anda akan menggunakan sumber daya yang sama. Benar kan?
A. Dijawab di atas.
A. Dijawab di atas.
A. Hibernate tidak tahu apa-apa tetapi Anda dapat menggunakan cache IMDG / terdistribusi pihak ketiga lainnya untuk diimplementasikan sebagai cache tingkat kedua hibernasi dan membuatnya tidak valid. misalnya TayzGrid adalah salah satu produk tersebut dan saya kira masih ada lagi.
sumber
Cache tingkat kedua Hibernate agak rumit untuk dipahami dan diterapkan. Inilah yang dapat kami katakan berdasarkan pertanyaan Anda:
Seperti yang Anda sarankan, cache Hibernate L2 (jika diaktifkan; tidak diaktifkan secara default) hanya ditanyakan setelah cache L1. Ini adalah cache nilai kunci yang datanya disimpan di beberapa sesi.
Cache kueri akan menjadi pilihan terbaik untuk kasus penggunaan ini, karena data pelanggan bersifat statis dan diambil dari database relasional.
Itu tergantung pada strategi cache Hibernate spesifik yang Anda gunakan. Hibernate sebenarnya memiliki empat strategi cache yang berbeda:
READ_ONLY : Objek tidak berubah sekali di dalam cache.
NONSTRICT_READ_WRITE : Objek berubah (akhirnya) setelah entri database yang sesuai diperbarui; ini menjamin konsistensi akhirnya.
READ_WRITE : Objek berubah (segera) setelah entri database yang sesuai diperbarui; ini menjamin konsistensi yang kuat dengan menggunakan kunci "lunak".
TRANSAKSI : Objek berubah menggunakan transaksi XA terdistribusi, memastikan integritas data; ini menjamin kesuksesan total atau mengembalikan semua perubahan. Namun, dalam keempat kasus ini, memperbarui satu entri database tidak akan membatalkan seluruh daftar pelanggan di cache. Hibernate sedikit lebih pintar dari itu :)
Untuk mempelajari lebih lanjut tentang cara kerja cache L2 dalam Hibernate, Anda dapat melihat artikel "Apa itu cache Hibernate L2," atau artikel mendalam Caching dalam Hibernate dengan Redis
sumber