4.1 Transaktioner og databaseintegritet

Den normale driftsform for en database er, når den modtager tusindvis af anmodninger hvert minut fra hundredvis af forskellige klienter. I dette tilfælde opstår der ofte situationer, når de samme data tilgås fra forskellige forespørgsler.

Sjældnere, men igen, fra tid til anden er der situationer, hvor en anmodning læser en bestemt linje, og en anden anmodning ændrer den på samme tid. Forestil dig, hvad der sker, hvis nogen læser en linje, der kun er halvt ændret? Intet godt.

Dette problem løses på flere måder. Først kan du bare låse den linje, der ændres. Både til at læse og skrive. Denne metode virker, men basens hastighed lider meget.

Den anden måde er at låse strengen til kun at skrive. Der vil dog stadig være et problem, når nogen forsøger at læse den delvist ændrede linje. Konklusion - der bør ikke være en situation, hvor linjen er delvist ændret.

Derfor kom de med en tredje metode - transaktioner. En transaktion er en gruppe af handlinger, der udføres enten alle sammen eller slet ingen. Der kan ikke være en situation, hvor en del af handlingerne blev udført, og den anden del ikke blev. Hvis det ikke er muligt at foretage alle ændringerne, rulles alle de allerede foretagede ændringer tilbage.

Enhver moderne SQL-server giver dig mulighed for kun at ændre data i transaktioner. Du åbner en transaktion, foretager ændringer i et vilkårligt antal tabeller og forpligter transaktionen. SQL Server forsøger derefter at foretage ændringer. Hvis alt er fint, vil de blive tilføjet til den generelle database. Hvis der var problemer, vil alle ændringer blive annulleret.

Hibernate bruger også dette paradigme. Derfor så vi i det forrige foredrag, at når man forsøgte at gemme Employee-objektet i databasen, blev der først åbnet en transaktion, og efter at have gemt den blev den commited.

Vi vil gå ind i dette emne mere detaljeret, men for nu, ved bare, hvorfor transaktioner er nødvendige, og hvor de normalt bruges.

4.2 Hentning af genstande

Hvis Hibernate udfører en anmodning om at få data, er der ingen grund til eksplicit at åbne en transaktion. Hibernate selv vil gøre dette, hvis det finder det passende: det har sine indstillinger såvel som indstillingerne for SQL-serveren.

Vi vil analysere, hvordan man arbejder med databasen. Og den enkleste af dem er at få et objekt ved dets ID . For at gøre dette skal du bruge metoden get()sessionsobjektet . Den generelle form for en sådan anmodning:

Class Name = session.get(Class.class, ID);

Eksempel:

public User getUserById(Integer id) {
    try (Session session = sessionFactory.openSession()) {
        User user = session.get(User.class, id);
        return user;
    }
}

4.3 Gem (tilføje) objekter

Hvis du vil gemme dit objekt i databasen, vil en forespørgsel blive udført på SQL-niveauINDSÆT. Derfor skal dine handlinger udføres som en separat transaktion. Det er også bedre at bruge persist()sessionsobjektets metode til persistens .

Den generelle form for en sådan anmodning:

session.persist(An object);

Metoden persist()ændrer ikke kun basen, men også selve objektet. Sagen er, at når vi tilføjer et objekt til databasen, har dette objekt endnu ikke sit eget ID , før det tilføjes . Nå, normalt så, selvom der er nuancer. Og efter tilføjelse har objektet allerede et ID .

public boolean saveUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.persist(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

Session- objektet har også en metode save(), der udfører en lignende funktion. Det er bare, at metoden save()er den gamle Hibernate-standard, og metoden persist()er JPA-standarden.

4.4 Sletning af objekter

Hvis du ønsker at slette et eksisterende objekt, så er det meget nemt at gøre det. For at gøre dette har sessionsobjektet en speciel metode - remove().

Den generelle form for en sådan anmodning:

session.remove(An object);

Og lad os selvfølgelig skrive koden med et eksempel:

public boolean removeUser(User user) {
    try (Session session = sessionFactory.openSession()) {
            Transaction transaction = session.beginTransaction();
            session.remove(user);
            transaction.commit();
            return true;
    }
    catch() {
    return false;
   	}
}

Hvorfor er det så svært, spørger du?

Nå, først og fremmest har enhver ændring af databasen altid forskellige og ikke altid indlysende konsekvenser. Og for det andet kan dette objekt have underordnede objekter tilknyttet, osv. Så sletningsscenarier er ofte ikke-trivielle.