Samtidighedsstrategier

Når du har aktiveret cachelagring på andet niveau i Hibernate, skal du forklare Hibernate, hvilke enhedsobjekter vi ønsker at cache og hvordan.

For at gøre dette har Hibernate en særlig anmærkning til Entity-klasser - @Cache . Eksempel:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

Denne annotation skal skrives for hver enhed, som vi ønsker at bruge cachen på andet niveau til. 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 adgangsstrategier for en cachelagret enhed, hvis den tilgås fra forskellige tråde:

  • Læs kun
  • læse skrive
  • ikke-streng-læse-skrive
  • transaktionelle

Skrivebeskyttet . En datatilpasset samtidighedsstrategi, der aldrig ændres. Hibernate vil simpelthen gemme disse objekter i sin hukommelse. Brug det kun til referencedata.

Databaser gemmer en masse information, som aldrig ændres. For eksempel gemmer en tabel en liste over begivenheder, der kun tilføjes, men aldrig ændres eller fjernes. Hvis du har brug for at arbejde med denne tabel gennem Hibernate, så vil den skrivebeskyttede caching-strategi passe til dig.

Læs-skriv (læs-skriv). Brug denne strategi til data, der primært er læsbare. Dog vil Hibernate spore forsøg på at ændre disse data, selvom det forventer, at de er meget sjældne.

Du skal primært cache de objekter, der sjældent ændres og ofte læses/anmodes. Hvis du har sådanne objekter, skal du bruge læse-skrive-strategien til dem.

Ikke-streng-læse-skrive . Denne strategi garanterer ikke overensstemmelse mellem cachen og databasen. Brug denne strategi, hvis dataene næsten aldrig ændres, og en lille chance for forældede data ikke er et kritisk problem.

I modsætning til læse-skrive-strategien antager denne strategi, at mutable data ikke er låst til læsning. Dette kan resultere i, at objektet ændres ét sted, mens nogen læser den gamle version af det et andet.

For eksempel har en bruger ændret sin kommentar, men andre brugere ser stadig hans gamle version i nogen tid. Hvis dette ikke er et problem for dig, så brug ikke-streng-læse-skriv-strategien.

Transaktionel . Brug denne strategi til primært skrivebeskyttede data, hvor det er vigtigt at forhindre forældede data i samtidige transaktioner i sjældne tilfælde med en opdatering.

Lagring af data i en cache

En anden vigtig detalje om cachen på andet niveau, som du bør huske, er, at Hibernate ikke selv gemmer objekterne i dine klasser. Det gemmer information som arrays af strenge, tal osv.

Og objektidentifikatoren fungerer som en pegepind til denne information. Begrebsmæssigt er dette noget som et kort, hvor objektets id er nøglen, og dataarrayerne er værdien. Du kan forestille dig det sådan her:

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

Hvilket er meget rimeligt i betragtning af hvor meget ekstra hukommelse hvert objekt fylder.

Ud over ovenstående skal du huske, at afhængighederne af din Entity-klasse heller ikke cachelagres som standard. Hvis vi for eksempel betragter klassen ovenfor, Employee , vil opgavesamlingen ved hentning blive hentet fra databasen , og ikke fra andet niveaus cache .

Hvis du også vil cache afhængigheder, så skal klassen se sådan ud:

@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 sidste detalje - læsning fra cachen på andet niveau sker kun, hvis det ønskede objekt ikke blev fundet i cachen på første niveau.

CacheMode

Hibernate giver mulighed for meget fleksibel cachehåndtering. Du kan indstille cachetilstanden for hver enkelt session eller endda for hver databaseanmodning.

Der er fem sådanne tilstande:

  • IGNORERE
  • NORMAL
  • SÆTTE
  • OPDATER

Tabellen nedenfor beskriver deres arbejde:

CacheMode Beskrivelse
Data læses fra cachen, men føjes ikke til den.
IGNORERE Sessionen interagerer ikke med cachen.
NORMAL Data læses fra cachen og føjes til den.
SÆTTE Data tages aldrig fra cachen, men tilføjes til den.
OPDATER Data tages aldrig fra cachen, men tilføjes til den. I denne tilstand bruges hibernate.cache.use_minimal_puts-indstillingen yderligere.

Et eksempel på indstilling af cachetilstand for en session:

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

Og også et eksempel på indstilling af tilstanden for sessionen og anmodningen:

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();