CodeGym /Kurslar /SQL SELF /SAVEPOINT-dən istifadə edərək tranzaksiyalar...

SAVEPOINT-dən istifadə edərək tranzaksiyalarda qismən geri qaytarmalara nəzarət

SQL SELF
Səviyyə , Dərs
Mövcuddur

Təsəvvür elə, kitab yazırsan. Amma bax, hər şey həmişə plan üzrə getmir. Bəzən bütöv bir fəsil yazırsan, amma oxuyanda başa düşürsən ki, 5-ci paraqraf lap bərbad alınıb. Nə edirsən? Bütün fəsli zibilə atmırsan axı, düzdür? Sadəcə problemli yerləri düzəldirsən.

SAVEPOINT PostgreSQL-də də təxminən belə işləyir. O sənə imkan verir ki:

  1. Tranzaksiyanın içində yaddaş nöqtələri yaradasan — kitabda bookmark qoymaq kimi.
  2. Bu nöqtələrə qayıdıb, yalnız həmin andan sonrakı əməliyyatları geri qaytarasan, bütün tranzaksiyanı yox.
  3. Qalan datalarla işləməyə davam edəsən, hər şeyi sıfırdan başlamağa ehtiyac olmadan.

SAVEPOINT-in əsas sintaksisi

SAVEPOINT-dən istifadə üçün komandalar çox sadədir. Əsas dəst belədir:

Yaddaş nöqtəsi yaratmaq (SAVEPOINT):

SAVEPOINT savepoint_name;

Bu, sanki deyirsən: "Gəlin bu yeri yadda saxlayaq, bəlkə sonra qayıtmaq lazım oldu."

Yaradılmış yaddaş nöqtəsinə geri qayıtmaq (ROLLBACK TO SAVEPOINT):
ROLLBACK TO SAVEPOINT savepoint_name;

Nəsə düz getməsə, göstərilən SAVEPOINT-ə qayıdırsan və həmin andan bəri olan bütün dəyişiklikləri ləğv edirsən.

Yaddaş nöqtəsini silmək (RELEASE SAVEPOINT):
RELEASE SAVEPOINT savepoint_name;

Bu, bookmark qoyduğun yeri "boşaldır". Bundan sonra artıq o nöqtəyə qayıda bilməyəcəksən.

Sadə nümunə: onlayn mağazada alış

Gəlin təsəvvür edək ki, onlayn mağazanı idarə edirik. Müştəri səbətə bir neçə məhsul əlavə edir və biz tranzaksiya aparmaq istəyirik: sifarişin rəsmiləşdirilməsi və anbar qalığının dəyişməsi. Amma əgər hansısa mərhələdə problem çıxsa, bütün tranzaksiyanı yox, yalnız bir hissəni geri qaytarmaq istəyirik.

BEGIN;

-- Addım 1: "SQL Kitabı" məhsulunu rezerv et
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;

-- Yaddaş nöqtəsi yaradırıq
SAVEPOINT book_reserved;

-- Addım 2: "PostgreSQL Krujka"sını rezerv et
UPDATE inventory SET stock = stock - 1 WHERE product_id = 102;

-- Ay-ay, məlum oldu ki, anbarda krujka yoxdur!
ROLLBACK TO SAVEPOINT book_reserved;

-- Yalnız kitab üçün dəyişiklikləri təsdiqləyirik
COMMIT;

Bu nümunədə nə baş verir?

  1. BEGIN ilə tranzaksiyaya başladıq.
  2. Kitabı rezerv edəndən sonra book_reserved yaddaş nöqtəsi yaratdıq. Bu bizim ilk "checkpoint" oldu.
  3. Krujkanı rezerv etmək istədik, amma səhv çıxdı (məsələn, anbarda lazım olan məhsul yox idi).
  4. book_reserved yaddaş nöqtəsinə qayıtdıq və yalnız krujka ilə bağlı dəyişiklikləri ləğv etdik.
  5. Sonda COMMIT ilə kitab üçün dəyişiklikləri təsdiqlədik.

Daha çətin nümunə: çoxmərhələli data işləmə

İndi təsəvvür elə, sifariş idarəetmə sistemi ilə işləyirsən və bir neçə cədvəli yeniləməlisən: orders (sifarişlər), inventory (anbar qalığı) və billing (hesablar). Hansısa mərhələdə problem olsa, digər cədvəllərdəki irəliləyiş itməsin istəyirsən. Bax, burada SAVEPOINT köməyə gəlir.

BEGIN;

-- Addım 1: Yeni sifariş yarat
INSERT INTO orders (order_id, customer_id, status) VALUES (1, 123, 'pending');
SAVEPOINT after_order_created;

-- Addım 2: Anbar qalığını yenilə
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
SAVEPOINT after_stock_updated;

-- Addım 3: Ödənişi həyata keçir
INSERT INTO billing (order_id, amount, status) VALUES (1, 100, 'paid');

-- Ay, səhv: kredit kartı rədd edildi!
ROLLBACK TO SAVEPOINT after_stock_updated;

-- Anbar yeniləndikdən sonrakı addıma qayıtdıq, amma sifariş "pending" statusunda qalır.
UPDATE orders SET status = 'failed' WHERE order_id = 1;

COMMIT;

Fikir ver, SAVEPOINT ilə tranzaksiyanı məntiqi mərhələlərə böldük və lazım olan nöqtəyə qayıdıb bir hissə dəyişiklikləri saxladıq.

SAVEPOINT ilə işləyərkən faydalı məsləhətlər

  • Yaddaş nöqtələrinə mənalı adlar ver. Yuxarıdakı nümunələrdə after_order_created sadəcə step1-dan qat-qat informativdir.
  • Daxili yaddaş nöqtələri problemsiz işləyir: başqa nöqtəyə geri qayıtdıqdan sonra da SAVEPOINT yarada bilərsən.
  • Lazımsız yaddaş nöqtələrini RELEASE SAVEPOINT ilə sil, resursları boşalt. Xüsusən böyük tranzaksiyalarda bu performansı artıra bilər.

Real istifadə ssenariləri

Bank əməliyyatlarının işlənməsi: Məsələn, bir neçə hesab arasında məbləğ köçürəndə, hansısa köçürmə uğursuz olsa, müəyyən mərhələyə qayıda bilərsən.

Fayllardan data importu: Böyük CSV fayl import edirsənsə, hər sətri yoxlaya və yalnız səhv olan datalar üçün rollback edə bilərsən, uğurluları saxlayaraq.

Kütləvi yazıların yenilənməsi: Minlərlə sətrin yeniləndiyi mürəkkəb SQL skriptində, SAVEPOINT icra ortasında səhv çıxsa, əvvəlki mərhələyə qayıtmağa imkan verir.

Tipik səhvlər və tələlər

Bəzən SAVEPOINT istifadə edəndə, necə işlədiyini tam başa düşməsən, gözlənilməz nəticələr ala bilərsən. Məsələn:

  • Əgər yaddaş nöqtəsinə rollback etməyi və ya onu silməyi unutsan, tranzaksiya bitənə qədər resurslar bloklana bilər.
  • SAVEPOINT yaddaş nöqtəsi yaradılmamışdan əvvəl olan əməliyyatları geri qaytara bilmir. Məsələn, COMMIT ilə təsdiqlənmiş datanı artıq rollback etmək olmur.

İndi tranzaksiyalarda rahatca eksperiment edə bilərsən, lazım olan yerlərdə yaddaş nöqtələri yaradaraq. Qarşıda daha çox SQL praktikasına hazır ol, yeni macəralar gəlir!

2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
Sadə dəyişikliklərin ləğvi `SAVEPOINT` ilə
Sadə dəyişikliklərin ləğvi `SAVEPOINT` ilə
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION