Samtidighetsstrategier

Etter at du har aktivert caching på andre nivå i Hibernate, må du forklare Hibernate hvilke Entity-objekter vi vil bufre og hvordan.

For å gjøre dette har Hibernate en spesiell merknad for Entity-klasser - @Cache . Eksempel:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

Denne merknaden må skrives for hver Entity-enhet som vi ønsker å bruke cachen på andre nivå for. Eksempel:

@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
    @Id
    private Integer id;
    private Set<Task> tasks;
}

Hibernate har 4 mulige tilgangsstrategier for en bufret enhet hvis den er tilgjengelig fra forskjellige tråder:

  • skrivebeskyttet
  • Les Skriv
  • ikke-streng-lese-skrive
  • transaksjonelle

Skrivebeskyttet . En datatilpasset samtidighetsstrategi som aldri endres. Hibernate vil ganske enkelt lagre disse objektene i minnet. Bruk den kun for referansedata.

Databaser lagrer mye informasjon som aldri endres. For eksempel holder en tabell en liste over hendelser som bare legges til, men aldri endres eller fjernes. Hvis du trenger å jobbe med denne tabellen gjennom Hibernate, vil den skrivebeskyttede caching-strategien passe deg.

Lese-skrive (lese-skrive). Bruk denne strategien for data som primært er lesbare. Hibernate vil imidlertid spore forsøk på å endre disse dataene, selv om det forventer at de vil være svært sjeldne.

Du må cache hovedsakelig de objektene som sjelden endres og ofte blir lest / etterspurt. Hvis du har slike objekter, må du bruke lese-skrive-strategien for dem.

Ikke-streng-les-skriv . Denne strategien garanterer ikke konsistens mellom hurtigbufferen og databasen. Bruk denne strategien hvis dataene nesten aldri endres og en liten sjanse for foreldede data ikke er et kritisk problem.

I motsetning til lese-skrive-strategien, antar denne strategien at mutable data ikke er låst for lesing. Dette kan føre til at objektet endres på ett sted, mens noen leser den gamle versjonen på et annet.

For eksempel har en bruker endret kommentaren sin, men andre brukere ser fortsatt den gamle versjonen hans en stund. Hvis dette ikke er et problem for deg, bruk ikke-streng-les-skriv-strategien.

Transaksjonelle . Bruk denne strategien for primært skrivebeskyttede data der det er viktig å forhindre foreldede data i samtidige transaksjoner i den sjeldne anledningen med en oppdatering.

Lagre data i en cache

En annen viktig detalj om cachen på andre nivå som du bør huske er at Hibernate ikke lagrer objektene til klassene dine selv. Den lagrer informasjon som arrays av strenger, tall, etc.

Og objektidentifikatoren fungerer som en peker til denne informasjonen. Konseptuelt er dette noe som et kart, der id-en til objektet er nøkkelen, og datamatrisene er verdien. Du kan forestille deg det slik:

1 -> { "Ivanov", 1, null , {1,2,5} }
2 -> { "Petrov", 2, null , {1,2,5} }
3 -> { "Sidorov", 3, null , {1,2,5} }

Noe som er veldig rimelig med tanke på hvor mye ekstra minne hvert objekt tar opp.

I tillegg til det ovennevnte, bør du huske at avhengighetene til Entity-klassen din heller ikke bufres som standard. Hvis vi for eksempel vurderer klassen ovenfor, Employee , vil oppgavesamlingen hentes fra databasen , og ikke fra andrenivå-cachen ved henting .

Hvis du vil bufre avhengigheter også, bør klassen se slik ut:

@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
    @Id
    private Integer id;

   @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
   private Set<Task> tasks;
}

Og den siste detaljen - lesing fra cachen på andre nivå skjer bare hvis ønsket objekt ikke ble funnet i cachen på første nivå.

CacheMode

Hibernate gir svært fleksibel cachingadministrasjon. Du kan angi hurtigbuffermodus for hver enkelt økt eller til og med for hver databaseforespørsel.

Det er fem slike moduser:

  • OVERSE
  • NORMAL
  • SETTE
  • FORFRISKE

Tabellen nedenfor beskriver arbeidet deres:

CacheMode Beskrivelse
Data leses fra hurtigbufferen, men legges ikke til den.
OVERSE Økten samhandler ikke med hurtigbufferen.
NORMAL Data leses fra hurtigbufferen og legges til den.
SETTE Data blir aldri hentet fra cachen, men lagt til den.
FORFRISKE Data blir aldri hentet fra cachen, men lagt til den. I denne modusen brukes i tillegg hibernate.cache.use_minimal_puts-innstillingen.

Et eksempel på innstilling av hurtigbuffermodus for en økt:

session.setCacheMode(CacheMode.GET);
Employee director = session.createQuery("from Employee where id = 4").uniqueResult();

Og også et eksempel på innstilling av modus for økten og forespørselen:

session.setCacheMode(CacheMode.GET);
Query query = session.createQuery("from Employee where id = 4");
query.setCacheMode(CacheMode.IGNORE); // Ignore cache work for this request
Employee director = query.uniqueResult();