Hibernate cache delle query - per gli oggetti non presenti nella cache di 2 ° livello - rischioso? utile? cattiva pratica?

StackOverflow https://stackoverflow.com/questions/1998326

Domanda

In relazione a questa domanda

Premessa:

Queste sono le mie assunzioni, basate sulla mia lettura, esperienza e comprensione, possono essere sbagliato, se lo sono, si prega di commento e Io modificare la domanda.

  • La cache di query è un bene per lo più lungo con cache di 2 ° livello
  • cache delle query memorizza nella cache i risultati delle query identificatori + parametri
  • La cache delle query è rischioso se il database è stato cambiato, e non si è riflesso nella cache

Domanda:

Ho un oggetto che non si trova nella cache di 2 ° livello. A causa di alcune cattive di programmazione o di altri vincoli, il codice che carica l'oggetto viene chiamato più volte nella stessa sessione di ibernazione. Il retrival sta usando una query ritrovamento HQL per esempio.

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);

Prima di aggiungere cache delle query, se il codice di cui sopra è stato chiamato N volte all'interno della stessa sessione Hibernate, c'erano N colpisce al database

Poi ho voluto vedere cosa succede se aggiungo cache delle query:

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();

Quando ho aggiunto cache delle query, ho notato che durante la stessa sessione, Hibernate non ha colpito i tempi di database N più, solo una volta per sessione.

  1. Quindi la mia prima ipotesi è che Hibernate prime ricerche nel Session Cache, poi nel 2 ° Livello Cache. E 'questa ipotesi è corretta?
  2. I anche assumere che se l'oggetto (Foo), che non si trova nella cache di 2 ° livello, è stato cambiato nel database, poi interrogare la cache, essendo sessione croce ambito, restituirà gli identificatori sbagliate, e quindi gli oggetti sbagliati. E 'corretto?
  3. E 'quindi giusto dire che l'utilizzo di cache delle query per le query che includono informazioni immutabili anche per oggetti non 2L memorizzati nella cache, è una buona pratica? (Ad esempio una query che la sua clausola WHERE contiene una condizione che sarà sempre tornare gli stessi risultati, ad esempio, "selezionare p.ser_num dove p.id =?", Quando SER_NUM e id coppie non cambiano una volta creato)

Tra l'altro, nella relativa domanda si sostiene che cache delle query non funziona sulla portata sessione cache. Sto missunderstanding tale affermazione, o qualsiasi altra cosa?

È stato utile?

Soluzione

La cache query è un particolare tipo di cache di 2 ° livello. Cosa si fa riferimento alla cache di 2 ° livello come io preferirei chiamare "cache degli oggetti".

commenti sul tuo ipotesi:

  
      
  • cache delle query è buono per lo più con cache di 2 ° livello (aka oggetto   cache).
  •   

Una cache delle query contiene solo i risultati delle prime query come chiavi primarie, in Hibernate parlare, id. Non tiene gli oggetti reali idratati. Questo ha senso, come quando si esegue una query con JDBC solo in realtà ti dà gli oggetti di nuovo idrati (popolate) e di eseguire iterazioni su ResultSet. L'affermazione non è necessariamente corretto. Se la query è molto complicato e richiede quindi un tempo molto lungo per l'esecuzione, utilizzando una cache delle query si risparmia tempo. Non sarà, utilizzando una cache delle query, risparmiare il tempo necessario per caricare gli oggetti dal database.

  
      
  • cache delle query è rischioso se il database è stato cambiato, e non si è riflesso   alla cache
  •   

Questo è vero, ma non è unica per interrogare la cache, lo stesso vale per quello che cache di 2 ° livello termine, ma quello che viene in genere chiamato cache degli oggetti.

  

Così la mia prima ipotesi è che   Hibernate prime ricerche nel   Sessione Cache, poi nel 2 ° Livello   Cache. E 'questa ipotesi è corretta?

Sì, quando si carica gli oggetti questo è il comportamento.

  

Suppongo inoltre che se l'oggetto (Foo)   che non è nella cache di 2 ° livello,   è stato cambiato nel database, allora   cache delle query, la sessione di essere croce   ambito, restituirà il torto   identificatori, e quindi dalla parte del torto   oggetti. E 'corretto?

Si, sia la cache oggetto e la cache delle query saranno interessati. Questo è solo di preoccupazione se il database viene modificato senza passare tramite Hibernate. È potenzialmente possibile attenuare l'effetto di questo impostando il timeout della cache delle query.

  

E 'quindi giusto dire che l'utilizzo   cache delle query per le query che includono   Informazioni immutabile anche per i non 2L   oggetti memorizzati nella cache, è una buona pratica?   (Ad esempio una query che la sua clausola dove   contiene una condizione che sarà sempre   lo stesso risultato, ad esempio "Selezionare   p.ser_num dove p.id =?" quando SER_NUM   e le coppie id non cambiano una volta   creato)

Per questi tipi di oggetti non c'è alcuna ragione per non utilizzare sia una cache oggetto e una cache delle query.

E sì, cache delle query non funziona a livello di sessione aka Livello 1 cache. Così il motivo per cui quando si esegue di nuovo la query colpisce nuovamente il database. Non metterà il risultato (set id) di una query nella cache di sessione.

Altri suggerimenti

solo supposizioni :

In base a questo articolo da Hibernate documentazione:

  

[cache delle query] crea due nuova cache   regioni: uno in possesso di cache di query   set di risultati   (Org.hibernate.cache.StandardQueryCache),   gli altri timestamp della azienda   la maggior parte degli aggiornamenti recenti di queryable   tavoli   (Org.hibernate.cache.UpdateTimestampsCache).

Presumo che ciò significa che ogni volta che il timestamp della tabella queryable è più recente il risultato-set - causerà ibernazione per avvicinarsi al DB nel il prossimo invito a tale query, e che ciò che mantenere la cache delle query al sicuro in qualche aspetto.

Ma 2 frasi più avanti nello stesso paragrafo della documentazione che dice:

  

La cache delle query deve essere sempre utilizzato   in combinazione con il secondo livello   cache.

ancora una volta, la mia ipotesi è che questo è l'unico modo di sospensione può essere a conoscenza di modifiche al database che sono state svolte dalla sessione di questo utente specifico

Per la vostra domanda # 3, non credo che si desidera utilizzare la cache delle query quando gli oggetti non vengono memorizzati nella cache. Vi ritroverete con tutti gli ID primarie, ma dovrà colpire il database di una volta per la chiave per recuperare gli oggetti che potrebbero essere più lento di esecuzione della query nella cache senza affatto. A partire dal 3.3 in ogni caso, forse in versioni più recenti si afferra gli oggetti mancanti utilizzando un minor numero di query, per esempio dove id in (: id1,: ID2, ...).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top