sql >> Database >  >> RDS >> Database

Transacties in SQL begrijpen

Een transactie in SQL is een uitvoeringseenheid die een of meer taken groepeert. Een transactie wordt als succesvol beschouwd als alle taken erin foutloos worden uitgevoerd.

Als een van de taken binnen een transactie echter niet wordt uitgevoerd, mislukt de hele transactie. Een transactie heeft slechts twee resultaten:succesvol of mislukt.

Een praktisch scenario

Beschouw een praktisch voorbeeld van een geldautomaat (Automated Teller Machine). Je gaat naar de geldautomaat en die vraagt ​​om je kaart. Het voert een query uit om te controleren of de kaart geldig is of niet. Vervolgens wordt u om uw pincode gevraagd. Opnieuw voert het een zoekopdracht uit om de pincode te matchen. De geldautomaat vraagt ​​u vervolgens om het bedrag dat u wilt opnemen en u vult het gewenste bedrag in. De geldautomaat voert nog een zoekopdracht uit om dat bedrag van uw rekening af te schrijven en geeft het geld vervolgens aan u uit.

Wat als het bedrag van uw rekening wordt afgeschreven en het systeem crasht door een stroomstoring zonder dat de bankbiljetten worden uitgegeven?

Dit is problematisch omdat de klant het geld heeft afgeschreven zonder geld te hebben ontvangen. Dit is waar transacties handig kunnen zijn.

In het geval van een systeemcrash of een andere fout, worden alle taken binnen de transactie teruggedraaid. Daarom wordt in het geval van een geldautomaat het bedrag teruggestort op uw rekening als u het om welke reden dan ook niet kunt opnemen.

Wat is een transactie?

Op zijn eenvoudigst is een wijziging in een databasetabel een transactie. Daarom zijn INSERT-, UPDATE- en DELETE-statements allemaal transactie-statements. Wanneer u een query schrijft, wordt een transactie uitgevoerd. Deze transactie kan echter niet worden teruggedraaid. We zullen hieronder zien hoe transacties worden gemaakt, vastgelegd en teruggedraaid, maar laten we eerst wat dummy-gegevens maken om mee te werken.

De gegevens voorbereiden

Voer het volgende script uit op uw databaseserver.

CREATE DATABASE schooldb

CREATE TABLE student
(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender VARCHAR(50) NOT NULL,
    age INT NOT NULL,
    total_score INT NOT NULL,
    
 )

INSERT INTO student 

VALUES (1, 'Jolly', 'Female', 20, 500), 
(2, 'Jon', 'Male', 22, 545), 
(3, 'Sara', 'Female', 25, 600), 
(4, 'Laura', 'Female', 18, 400), 
(5, 'Alan', 'Male', 20, 500)

Het bovenstaande SQL-script creëert een database schooldb. In deze database wordt een tabelstudent gemaakt en worden enkele dummygegevens aan die tabel toegevoegd.

Query's uitvoeren zonder transacties

Laten we drie standaardquery's uitvoeren. We gebruiken momenteel geen transacties.

INSERT INTO student 
VALUES (6, 'Suzi', 'Female', 25, 395)

UPDATE student
SET age = 'Six' WHERE id= 6

DELETE from student
WHERE id = 6

Hier voegt de eerste query een studentrecord in de database in. De tweede query werkt de leeftijd van de leerling bij en de derde query verwijdert het nieuw ingevoegde record.

Als u het bovenstaande script uitvoert, zult u zien dat het record in de database wordt ingevoegd en dat er een fout optreedt tijdens het uitvoeren van de tweede query.

Als je naar de tweede zoekopdracht kijkt, werken we de leeftijd bij door een tekenreekswaarde op te slaan in de leeftijdskolom waarin gegevens van het type integer kunnen worden opgeslagen. Daarom wordt er een fout gegenereerd. De eerste query wordt echter nog steeds succesvol voltooid. Dit betekent dat als u alle records uit de studententabel selecteert, u een nieuw ingevoegd record zult zien.

[table id=23 /]

Je kunt zien dat het record met id=6 en de naam 'Suzi' is ingevoegd in de database. Maar de leeftijd kon niet worden bijgewerkt en de tweede query mislukte.

Wat als we dit niet willen? Wat als we er zeker van willen zijn dat alle query's met succes worden uitgevoerd of dat geen enkele query wordt uitgevoerd? Dit is waar transacties van pas komen.

Query's met transacties uitvoeren

Laten we nu de drie bovenstaande zoekopdrachten uitvoeren binnen een transactie.

Laten we eerst eens kijken hoe u een transactie aanmaakt en vastlegt.

Een transactie aanmaken

Als u een query/query's als transactie wilt uitvoeren, plaatst u de query's gewoon tussen de trefwoorden BEGIN TRANSACTION en COMMIT TRANSACTION. De BEGIN TRANSACTIE verklaart het begin van een TRANSACTIE, terwijl COMMIT TRANSACTIE aangeeft dat de transactie is voltooid.

Laten we drie nieuwe zoekopdrachten uitvoeren op de database die we eerder als transactie hebben gemaakt. We zullen een nieuw record toevoegen voor een nieuwe student met ID 7.

BEGIN TRANSACTION

	INSERT INTO student 
	VALUES (7, 'Jena', 'Female', 22, 456)

	UPDATE student
	SET age = 'Twenty Three' WHERE id= 7

	DELETE from student
	WHERE id = 7

COMMIT TRANSACTION

Wanneer de bovenstaande transactie wordt uitgevoerd, zal er opnieuw een fout optreden in de tweede zoekopdracht, aangezien er opnieuw een stringtypewaarde wordt opgeslagen in de leeftijdskolom waarin alleen gegevens van het gehele type worden opgeslagen.

Omdat de fout echter optreedt binnen een transactie, worden alle query's die met succes zijn uitgevoerd voordat deze fout optrad, automatisch teruggedraaid. Daarom wordt de eerste query die een nieuw studentenrecord invoegt met id =7 en naam 'Jena' ook teruggedraaid.

Als je nu alle records uit de studententabel selecteert, zul je zien dat het nieuwe record voor 'Jena' niet is ingevoegd.

Handmatige transactie terugdraaien

We weten dat als een zoekopdracht een fout veroorzaakt in een transactie, de hele transactie, inclusief alle reeds uitgevoerde zoekopdrachten, automatisch wordt teruggedraaid. We kunnen een transactie echter ook handmatig terugdraaien wanneer we maar willen.

Om een ​​transactie terug te draaien, wordt het trefwoord ROLLBACK gebruikt, gevolgd door de naam van de transactie. Om een ​​transactie een naam te geven, wordt de volgende syntaxis gebruikt:

BEGIN TRANSACTION Transaction_name

Stel dat we willen dat onze leerlingentabel geen records bevat met dubbele leerlingnamen. We voegen een record toe voor een nieuwe leerling. We gaan dan na of er een leerling in de database staat met een naam die identiek is aan de naam van de nieuw ingevoerde leerling. Als de student met die naam nog niet bestaat, zullen we onze transactie uitvoeren. Als er een student met die naam bestaat, zullen we onze transactie terugdraaien. We zullen gebruik maken van voorwaardelijke uitspraken in onze query.

Bekijk de volgende transactie:

DECLARE @NameCount int

BEGIN TRANSACTION AddStudent

	INSERT INTO student 
	VALUES (8, 'Jacob', 'Male', 21, 600)

	SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob'

	IF @NameCount > 1
		BEGIN 
			ROLLBACK TRANSACTION AddStudent
			PRINT 'A student with this name already exists'
		END
	ELSE
		BEGIN
			COMMIT TRANSACTION AddStudent
			PRINT 'New record added successfully'
		END

Kijk goed naar het bovenstaande script. Er gebeuren hier veel dingen.

In de eerste regel maken we een integer type SQL-variabele NameCount.

Vervolgens beginnen we een transactie met de naam 'AddStudent'. U kunt uw transactie een willekeurige naam geven.

In de transactie hebben we een nieuw record voor een student ingevoegd met id =8 en de naam 'Jacob'.

Vervolgens tellen we met behulp van de COUNT-aggregatiefunctie het aantal studentrecords met de naam 'Jacob' en slaan het resultaat op in de variabele 'NameCount'.

Als de waarde van de variabele groter is dan 1, betekent dit dat er al een student met de naam 'Jacob' in de database bestaat. In dat geval ROLLBACK we onze transactie en PRINT een bericht op het scherm dat 'Er bestaat al een student met deze naam'.

Zo niet, dan voeren we onze transactie uit en geven we het bericht 'Nieuw record succesvol toegevoegd' weer.

Als je bovenstaande transactie voor de eerste keer uitvoert, is er geen studentrecord met de naam 'Jacob'. Daarom wordt de transactie uitgevoerd en wordt het volgende bericht afgedrukt:

Probeer nu het volgende SQL-script op de server uit te voeren:

DECLARE @NameCount int

BEGIN TRANSACTION AddStudent

	INSERT INTO student 
	VALUES (9, 'Jacob', 'Male', 22, 400)

	SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob'

	IF @NameCount > 1
		BEGIN 
			ROLLBACK TRANSACTION AddStudent
			PRINT 'A student with this name already exists'
		END
	ELSE
		BEGIN
			COMMIT TRANSACTION
			PRINT 'New record added successfully'
		END

Ook hier voegen we het studentenrecord in met id =9 en de naam 'Jacob'. Aangezien er al een studentenrecord met de naam 'Jacob' in de database bestaat, wordt de transactie teruggedraaid en wordt het volgende bericht afgedrukt:

Nuttige links

  • Klassen over SQL-transacties

  1. Stappen om het beheerderswachtwoord te wijzigen dat is verloren of vergeten van een EBS WebLogic Domain R12.2

  2. Hoe de nieuwste MySQL 8 op Debian 10 te installeren

  3. MySQL - Krijg rijnummer bij selecteren

  4. GROUP BY in Postgres - geen gelijkheid voor JSON-gegevenstype?