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:
- Tranzaksiyanın içində yaddaş nöqtələri yaradasan — kitabda bookmark qoymaq kimi.
- Bu nöqtələrə qayıdıb, yalnız həmin andan sonrakı əməliyyatları geri qaytarasan, bütün tranzaksiyanı yox.
- 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.
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?
BEGINilə tranzaksiyaya başladıq.- Kitabı rezerv edəndən sonra
book_reservedyaddaş nöqtəsi yaratdıq. Bu bizim ilk "checkpoint" oldu. - Krujkanı rezerv etmək istədik, amma səhv çıxdı (məsələn, anbarda lazım olan məhsul yox idi).
book_reservedyaddaş nöqtəsinə qayıtdıq və yalnız krujka ilə bağlı dəyişiklikləri ləğv etdik.- Sonda
COMMITilə 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_createdsadə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
SAVEPOINTyarada bilərsən. - Lazımsız yaddaş nöqtələrini
RELEASE SAVEPOINTilə 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.
SAVEPOINTyaddaş nöqtəsi yaradılmamışdan əvvəl olan əməliyyatları geri qaytara bilmir. Məsələn,COMMITilə 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!
GO TO FULL VERSION