Samtidighetsstrategier

När du har aktiverat cachelagring på andra nivån i Hibernate måste du förklara för Hibernate vilka Entity-objekt vi vill cache och hur.

För att göra detta har Hibernate en speciell kommentar för Entity-klasser - @Cache . Exempel:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

Den här anteckningen måste skrivas för varje Entity-entitet som vi vill använda den andra nivåns cache för. Exempel:

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

Hibernate har 4 möjliga åtkomststrategier för en cachad enhet om den nås från olika trådar:

  • skrivskyddad
  • läsa skriva
  • icke-strikt-läsa-skriva
  • transaktionella

Endast läs . En dataanpassad samtidighetsstrategi som aldrig förändras. Hibernate kommer helt enkelt att lagra dessa objekt i sitt minne. Använd den endast för referensdata.

Databaser lagrar mycket information som aldrig förändras. En tabell har till exempel en lista över händelser som bara läggs till men som aldrig ändras eller tas bort. Om du behöver arbeta med den här tabellen via Hibernate, kommer den skrivskyddade cachningsstrategin att passa dig.

Läs-skriv (läs-skriv). Använd denna strategi för data som i första hand är läsbar. Hibernate kommer dock att spåra försök att ändra dessa data, även om det förväntar sig att de kommer att vara mycket sällsynta.

Du behöver cache huvudsakligen de objekt som sällan ändras och som ofta läses/efterfrågas. Om du har sådana objekt måste du använda läs-skriv-strategin för dem.

Icke strikt-läs-skriv . Denna strategi garanterar inte överensstämmelse mellan cachen och databasen. Använd den här strategin om data nästan aldrig ändras och en liten risk för inaktuell data inte är en kritisk fråga.

Till skillnad från läs-skriv-strategin antar denna strategi att föränderlig data inte är låst för läsning. Detta kan resultera i att objektet ändras på ett ställe, medan någon på en annan läser den gamla versionen av det.

En användare har till exempel ändrat sin kommentar, men andra användare ser fortfarande hans gamla version ett tag. Om detta inte är ett problem för dig, använd då den icke-striktade-läs-skriv-strategin.

Transaktionell . Använd denna strategi för primärt skrivskyddad data där det är viktigt att förhindra inaktuella data i samtidiga transaktioner vid det sällsynta tillfället av en uppdatering.

Lagra data i en cache

En annan viktig detalj om den andra nivåns cache som du bör komma ihåg är att Hibernate inte lagrar objekten i dina klasser själva. Den lagrar information som matriser av strängar, siffror, etc.

Och objektidentifieraren fungerar som en pekare till denna information. Begreppsmässigt är detta något som en karta, där objektets id är nyckeln och datamatriserna är värdet. Du kan föreställa dig det så här:

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

Vilket är mycket rimligt med tanke på hur mycket extra minne varje objekt tar upp.

Utöver ovanstående bör du komma ihåg att beroenden för din Entity-klass inte heller cachelagras som standard. Om vi ​​till exempel tar hänsyn till klassen ovan, Employee , kommer uppgiftsinsamlingen att hämtas från databasen och inte från den andra nivåns cacheminne vid hämtning .

Om du också vill cachelagra beroenden bör klassen se ut så här:

@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;
}

Och den sista detaljen - läsning från den andra nivåns cache sker endast om det önskade objektet inte hittades i den första nivåns cache.

Cacheläge

Hibernate möjliggör mycket flexibel cachehantering. Du kan ställa in cacheläget för varje enskild session eller till och med för varje databasförfrågan.

Det finns fem sådana lägen:

  • SKAFFA SIG
  • IGNORERA
  • VANLIGT
  • SÄTTA
  • UPPDATERA

Tabellen nedan beskriver deras arbete:

Cacheläge Beskrivning
SKAFFA SIG Data läses från cachen men läggs inte till den.
IGNORERA Sessionen interagerar inte med cachen.
VANLIGT Data läses från cachen och läggs till den.
SÄTTA Data tas aldrig från cachen, utan läggs till den.
UPPDATERA Data tas aldrig från cachen, utan läggs till den. I det här läget används dessutom inställningen hibernate.cache.use_minimal_puts.

Ett exempel på hur du ställer in cacheläget för en session:

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

Och även ett exempel på att ställa in läget för sessionen och begäran:

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