मेरा सुझाव है कि एक @Startup
जोड़ें @Singleton
वर्ग जो PostgreSQL डेटाबेस के लिए एक JDBC कनेक्शन स्थापित करता है और LISTEN
. का उपयोग करता है और NOTIFY
कैश अमान्यता को संभालने के लिए।
अपडेट करें :यहां एक और दिलचस्प तरीका है, pgq और अमान्यकरण के लिए श्रमिकों के संग्रह का उपयोग करना।
अमान्य संकेत
तालिका में एक ट्रिगर जोड़ें जिसे अपडेट किया जा रहा है जो एक NOTIFY
भेजता है जब भी किसी निकाय को अद्यतन किया जाता है। PostgreSQL 9.0 और इसके बाद के संस्करण पर NOTIFY
एक पेलोड हो सकता है, आमतौर पर एक पंक्ति आईडी, इसलिए आपको अपने पूरे कैश को अमान्य करने की आवश्यकता नहीं है, केवल वह इकाई जो बदल गई है। पुराने संस्करणों पर जहां पेलोड समर्थित नहीं है, आप या तो अमान्य प्रविष्टियों को टाइमस्टैम्प्ड लॉग टेबल में जोड़ सकते हैं, जब आपके सहायक वर्ग को NOTIFY
मिलता है। , या केवल संपूर्ण कैश को अमान्य कर दें।
आपका सहायक वर्ग अब LISTEN
पर NOTIFY
ट्रिगर भेजता है ईवेंट। जब उसे NOTIFY
मिलता है घटना, यह अलग-अलग कैश प्रविष्टियों को अमान्य कर सकता है (नीचे देखें), या पूरे कैश को फ्लश कर सकता है। आप PgJDBC के सुनने/सूचना समर्थन के साथ डेटाबेस से सूचनाएं सुन सकते हैं। आपको java.sql.Connection
द्वारा प्रबंधित किसी भी कनेक्शन पूलर को खोलना होगा अंतर्निहित PostgreSQL कार्यान्वयन तक पहुंचने के लिए ताकि आप इसे org.postgresql.PGConnection
पर डाल सकें और getNotifications()
. पर कॉल करें उस पर।
LISTEN
. का एक विकल्प और NOTIFY
, आप एक टाइमर पर एक परिवर्तन लॉग तालिका को मतदान कर सकते हैं, और समस्या तालिका पर एक ट्रिगर बदली हुई पंक्ति आईडी संलग्न कर सकते हैं और टाइमस्टैम्प को परिवर्तन लॉग तालिका में बदल सकते हैं। प्रत्येक डीबी प्रकार के लिए एक अलग ट्रिगर की आवश्यकता को छोड़कर यह दृष्टिकोण पोर्टेबल होगा, लेकिन यह अक्षम और कम समय पर है। इसे बार-बार अक्षम मतदान की आवश्यकता होगी, और अभी भी एक समय की देरी है कि सुनने/सूचित करने का दृष्टिकोण नहीं है। PostgreSQL में आप एक UNLOGGED
. का उपयोग कर सकते हैं इस दृष्टिकोण की लागत को थोड़ा कम करने के लिए तालिका।
कैश स्तर
एक्लिप्सलिंक/जेपीए में कैशिंग के कुछ स्तर हैं।
पहला स्तर कैश EntityManager
. पर है स्तर। अगर कोई इकाई EntityManager
से जुड़ी है द्वारा persist(...)
. द्वारा , merge(...)
, find(...)
, आदि, फिर EntityManager
उस इकाई के समान उदाहरण को वापस करने के लिए आवश्यक है जब इसे उसी सत्र में फिर से एक्सेस किया जाता है, तो आपके आवेदन में अभी भी इसका संदर्भ है या नहीं। यदि आपकी डेटाबेस सामग्री बदल गई है, तो यह संलग्न इंस्टेंस अप-टू-डेट नहीं होगा।
दूसरा स्तर कैश, जो वैकल्पिक है, EntityManagerFactory
. पर है स्तर और एक अधिक पारंपरिक कैश है। यह स्पष्ट नहीं है कि आपके पास द्वितीय स्तर का कैश सक्षम है या नहीं। अपने एक्लिप्सलिंक लॉग और अपने persistence.xml
. की जांच करें . आप EntityManagerFactory.getCache()
के साथ दूसरे स्तर के कैश तक पहुंच प्राप्त कर सकते हैं; देखें Cache
।
@thedayofcondor ने दिखाया कि दूसरे स्तर के कैश को कैसे फ्लश करना है:
em.getEntityManagerFactory().getCache().evictAll();
लेकिन आप evict(java.lang.Class cls, java.lang.Object primaryKey)
से अलग-अलग ऑब्जेक्ट को बेदखल भी कर सकते हैं। कॉल करें:
em.getEntityManagerFactory().getCache().evict(theClass, thePrimaryKey);
जिसे आप अपने @Startup
. से इस्तेमाल कर सकते हैं @Singleton
NOTIFY
श्रोता केवल उन प्रविष्टियों को अमान्य करने के लिए जो बदल गई हैं।
पहला स्तर कैश इतना आसान नहीं है, क्योंकि यह आपके एप्लिकेशन लॉजिक का हिस्सा है। आप इस बारे में जानना चाहेंगे कि EntityManager
. कैसे , संलग्न और अलग संस्थाएं, आदि काम करते हैं। एक विकल्प हमेशा विचाराधीन तालिका के लिए पृथक इकाइयों का उपयोग करना है, जहां आप एक नए EntityManager
का उपयोग करते हैं जब भी आप इकाई लाते हैं। यह प्रश्न:
अमान्य JPA EntityManager सत्र
इकाई प्रबंधक के कैश की अमान्यता को संभालने की एक उपयोगी चर्चा है। हालांकि, इसकी संभावना नहीं है कि एक EntityManager
कैशे आपकी समस्या है, क्योंकि एक RESTful वेब सेवा आमतौर पर संक्षिप्त EntityManager
. का उपयोग करके कार्यान्वित की जाती है सत्र यह केवल एक समस्या होने की संभावना है यदि आप विस्तारित दृढ़ता संदर्भों का उपयोग कर रहे हैं, या यदि आप अपना स्वयं का EntityManager
बना रहे हैं और प्रबंधित कर रहे हैं कंटेनर-प्रबंधित दृढ़ता का उपयोग करने के बजाय सत्र।