Database
 sql >> Baza danych >  >> RDS >> Database

Zrozumienie transakcji w SQL

Transakcja w SQL jest jednostką wykonania, która grupuje jedno lub więcej zadań razem. Transakcja jest uważana za udaną, jeśli wszystkie zawarte w niej zadania są wykonywane bez błędów.

Jednakże, jeśli którekolwiek z zadań w ramach transakcji nie zostanie wykonane, cała transakcja zakończy się niepowodzeniem. Transakcja ma tylko dwa wyniki:udana lub nieudana.

Praktyczny scenariusz

Rozważmy praktyczny przykład bankomatu (automatycznego bankomatu). Idziesz do bankomatu, a on prosi o kartę. Uruchamia zapytanie, aby sprawdzić, czy karta jest ważna, czy nie. Następnie prosi o podanie kodu PIN. Ponownie uruchamia zapytanie, aby dopasować kod PIN. Bankomat poprosi Cię o kwotę, którą chcesz wypłacić, a Ty wprowadzisz żądaną kwotę. Bankomat wykonuje kolejne zapytanie, aby potrącić tę kwotę z Twojego konta, a następnie przekaże Ci środki.

Co się stanie, jeśli kwota zostanie potrącona z twojego konta, a następnie system ulegnie awarii z powodu awarii zasilania bez wydawania banknotów?

Jest to problematyczne, ponieważ klient ma potrącone środki bez otrzymania żadnych pieniędzy. W tym miejscu transakcje mogą być przydatne.

W przypadku awarii systemu lub innego błędu, wszystkie zadania w ramach transakcji zostaną wycofane. Dlatego w przypadku bankomatu kwota zostanie zwrócona na Twoje konto, jeśli z jakiegokolwiek powodu nie będziesz mógł jej wypłacić.

Co to jest transakcja?

Najprostsza zmiana w tabeli bazy danych jest transakcją. Dlatego wyciągi INSERT, UPDATE i DELETE są wyciągami transakcji. Kiedy piszesz zapytanie, wykonywana jest transakcja. Jednak tej transakcji nie można cofnąć. Zobaczymy, jak transakcje są tworzone, zatwierdzane i wycofywane poniżej, ale najpierw utwórzmy kilka fikcyjnych danych do pracy.

Przygotowywanie danych

Uruchom następujący skrypt na serwerze bazy danych.

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)

Powyższy skrypt SQL tworzy schooldb bazy danych. W tej bazie danych tworzona jest tabela student i do tej tabeli dodawane są niektóre dane fikcyjne.

Wykonywanie zapytań bez transakcji

Wykonajmy trzy standardowe zapytania. W tej chwili nie korzystamy z transakcji.

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

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

DELETE from student
WHERE id = 6

Tutaj pierwsze zapytanie wstawia rekord ucznia do bazy danych. Drugie zapytanie aktualizuje wiek ucznia, a trzecie zapytanie usuwa nowo wstawiony rekord.

Jeśli wykonasz powyższy skrypt, zobaczysz, że rekord zostanie wstawiony do bazy danych, a następnie wystąpi błąd podczas wykonywania drugiego zapytania.

Jeśli spojrzysz na drugie zapytanie, aktualizujemy wiek, przechowując wartość ciągu w kolumnie wiek, która może przechowywać dane typu liczb całkowitych. Dlatego zostanie zgłoszony błąd. Jednak pierwsze zapytanie nadal zakończy się pomyślnie. Oznacza to, że jeśli wybierzesz wszystkie rekordy z tabeli uczniów, zobaczysz nowo wstawiony rekord.

[identyfikator tabeli=23 /]

Widać, że rekord o id=6 i nazwie „Suzi” został wstawiony do bazy danych. Nie udało się jednak zaktualizować wieku, a drugie zapytanie nie powiodło się.

A co, jeśli tego nie chcemy? A co jeśli chcemy mieć pewność, że albo wszystkie zapytania zostaną wykonane pomyślnie, albo żadne z nich nie zostanie wykonane w ogóle? Tutaj przydają się transakcje.

Wykonywanie zapytań z transakcjami

Teraz wykonajmy trzy powyższe zapytania w ramach transakcji.

Najpierw zobaczmy, jak utworzyć i zatwierdzić transakcję.

Tworzenie transakcji

Aby uruchomić zapytanie/zapytania jako transakcję, po prostu umieść zapytania w słowach kluczowych BEGIN TRANSACTION i COMMIT TRANSACTION. BEGIN TRANSACTION deklaruje początek TRANSAKCJI, natomiast COMMIT TRANSACTION stwierdza, że ​​transakcja została zakończona.

Wykonajmy trzy nowe zapytania do bazy danych, którą utworzyliśmy wcześniej jako transakcję. Dodamy nowy rekord dla nowego ucznia z identyfikatorem 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

Kiedy powyższa transakcja zostanie wykonana, ponownie wystąpi błąd w drugim zapytaniu, ponieważ ponownie wartość typu string jest przechowywana w kolumnie age, która przechowuje tylko dane typu integer.

Jednakże, ponieważ błąd występuje wewnątrz transakcji, wszystkie zapytania, które zostały pomyślnie wykonane przed wystąpieniem tego błędu, zostaną automatycznie wycofane. W związku z tym pierwsze zapytanie, które wstawia nowy rekord ucznia o identyfikatorze =7 i nazwie „Jena”, również zostanie wycofane.

Teraz, jeśli wybierzesz wszystkie rekordy z tabeli uczniów, zobaczysz, że nowy rekord dla „Jeny” nie został wstawiony.

Ręczne przywracanie transakcji

Wiemy, że jeśli zapytanie spowoduje błąd w transakcji, cała transakcja, w tym wszystkie zapytania już wykonane, są automatycznie wycofywane. Możemy jednak również ręcznie wycofać transakcję ręcznie, kiedy tylko chcemy.

W celu wycofania transakcji używa się słowa kluczowego ROLLBACK, po którym następuje nazwa transakcji. Aby nazwać transakcję, używana jest następująca składnia:

BEGIN TRANSACTION Transaction_name

Załóżmy, że chcemy, aby nasza tabela uczniów nie zawierała rekordów zawierających zduplikowane nazwiska uczniów. Dodamy rekord dla nowego ucznia. Sprawdzimy wtedy, czy w bazie istnieje uczeń o nazwisku identycznym z nazwiskiem nowo wstawionego ucznia. Jeśli uczeń o tym nazwisku jeszcze nie istnieje, zatwierdzimy naszą transakcję. Jeśli uczeń o tym nazwisku istnieje, wycofamy naszą transakcję. W naszym zapytaniu użyjemy instrukcji warunkowych.

Spójrz na następującą transakcję:

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

Przyjrzyj się uważnie powyższemu skryptowi. Dużo się tu dzieje.

W pierwszym wierszu tworzymy zmienną SQL typu integer NameCount.

Następnie rozpoczynamy transakcję o nazwie „AddStudent”. Transakcji możesz nadać dowolną nazwę.

W ramach transakcji wstawiliśmy nowy rekord dla ucznia o id =8 i nazwisku „Jacob”.

Następnie, korzystając z funkcji agregującej LICZBA, zliczamy liczbę rekordów uczniów, których imię to „Jacob” i zapisujemy wynik w zmiennej „Imię Liczba”.

Jeśli wartość zmiennej jest większa niż 1, oznacza to, że uczeń o imieniu „Jacob” już istnieje w bazie. W takim przypadku cofamy naszą transakcję i DRUKUJEMY komunikat na ekranie, że „Student o tym nazwisku już istnieje”.

Jeśli nie, zatwierdzamy naszą transakcję i wyświetlamy komunikat „Nowy rekord został pomyślnie dodany”.

Gdy po raz pierwszy uruchomisz powyższą transakcję, nie będzie rekordu ucznia o imieniu „Jacob”. Dlatego transakcja zostanie zatwierdzona i zostanie wydrukowany następujący komunikat:

Teraz spróbuj uruchomić następujący skrypt SQL na serwerze:

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

Tutaj ponownie wstawiamy rekord ucznia o identyfikatorze =9 i nazwisku „Jacob”. Ponieważ rekord ucznia o imieniu „Jacob” już istnieje w bazie danych, transakcja zostanie wycofana i zostanie wydrukowany następujący komunikat:

Przydatne linki

  • Klasy dotyczące transakcji SQL

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak tworzyć procedury składowane w SQL?

  2. Zarządzanie rolami i statusami w systemie

  3. Ustawianie fizycznej gotowości Active Data Guard w architekturze RAC One Node — część 2

  4. Jak połączyć SalesForce jako źródło danych w Pyramid?

  5. Wynajem samochodów jest tak prosty jak prowadzenie pojazdu:model danych dla wypożyczalni samochodów