CodeGym /Kurslar /SQL SELF /İzolyasiya səviyyəsi READ COMMITTED

İzolyasiya səviyyəsi READ COMMITTED

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

Gəlin baxaq, READ COMMITTED izolyasiya səviyyəsi nə edir. Adından da bəlli olur ki, tranzaksiya çərçivəsində oxuduğumuz hər şey artıq başqa tranzaksiyalar tərəfindən "commit" olunub. Elə bil həyatda yalnız rəsmi protokolda yazılan dedi-qodulara inanırıq.

Ciddi desək, bu səviyyə zəmanət verir ki, tranzaksiya başqa tranzaksiyaların etdiyi, amma hələ commit olunmamış dəyişiklikləri görə bilməz. Bu, "çirkli oxuma" (Dirty Read) kimi tanınan problemi həll edir. Amma yadında saxla ki, oxuduğun məlumatlar dəyişə bilər, əgər başqa bir tranzaksiya sənin sorğuların arasında commit edərsə. Bu isə "təkrarlanmayan oxuma" (Non-Repeatable Read) riskini yaradır.

PostgreSQL-də READ COMMITTED izolyasiya səviyyəsi default olaraq təyin olunub. Yəni heç nəyi xüsusi qurmağa ehtiyac yoxdur, avtomatik bu rejimdə işləyir.

READ COMMITTED izolyasiya səviyyəsinin istifadə nümunəsi

Gəlin baxaq, bu praktikada necə işləyir. Təsəvvür elə ki, bizdə accounts adlı cədvəl var, burada istifadəçilər və onların balansları saxlanılır:

CREATE TABLE accounts (
    account_id SERIAL PRIMARY KEY,
    account_name TEXT NOT NULL,
    balance NUMERIC(10, 2) NOT NULL
);

INSERT INTO accounts (account_name, balance)
VALUES ('Alice', 1000.00), ('Bob', 500.00);

İndi belə bir vəziyyəti təsəvvür elə. Sessiya 1 və Sessiya 2 — bizim hekayənin iki qəhrəmanı, hər ikisi accounts cədvəli ilə işləyir. Bax, nə baş verir:

Sessiya 1:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';
-- Hələlik heç bir COMMIT və ya ROLLBACK yoxdur.

Bu anda Alice-in balance-ından müvəqqəti olaraq 100 çıxılıb, amma nəticə hələ commit olunmayıb.

Sessiya 2:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

BEGIN;
SELECT balance FROM accounts WHERE account_name = 'Alice';

Nəticə: Sessiya 2 Alice-in balansını 1000.00 kimi görür, çünki Sessiya 1-in tranzaksiyası hələ bitməyib (COMMIT edilməyib). READ COMMITTED səviyyəsi bizi "çirkli oxuma"dan qoruyur.

Sessiya 1 tranzaksiyanı bitirir:

COMMIT;

İndi Alice-in balansı yenilənib və bazada 900.00 kimi qeyd olunub.

Sessiya 2 sorğunu təkrar edir:

SELECT balance FROM accounts WHERE account_name = 'Alice';

Nəticə: indi Sessiya 2 Alice-in yenilənmiş balansını — 900.00 görür. Diqqət et, nəticə əvvəlki sorğudan fərqlidir, orada 1000.00 qaytarırdı. Bu, "təkrarlanmayan oxuma" problemidir.

READ COMMITTED nə vaxt istifadə olunur?

READ COMMITTED izolyasiya səviyyəsi performans və konsistentlik arasında balansdır. Amma bəzi situasiyalar var ki, burada bu səviyyə əla işləyir:

  1. Sadə CRUD əməliyyatları: sadəcə məlumat oxuyanda və ya yeniləyəndə, mürəkkəb əlaqələr olmadan.

  2. Yazıların yenilənməsi: məsələn, cədvəldə kütləvi yeniləmə edəndə, commit olunmuş dəyişiklikləri dərhal görmək vacib olanda.

  3. Tranzaksiya işlənməsi: ödəmə sistemləri, harada istifadəçilər yalnız təsdiqlənmiş məlumatları görə bilirlər.

Amma əgər mürəkkəb analitik sorğular edirsənsə və ya böyük həcmdə məlumatlarla işləyirsənsə, başqa izolyasiya səviyyəsinə, məsələn, REPEATABLE READ-ə baxmaq olar.

READ COMMITTED izolyasiya səviyyəsinin üstünlükləri və çatışmazlıqları

READ COMMITTED izolyasiya səviyyəsi elə bil qızıl ortadır. Səni çirkli məlumatdan qoruyur: başqa tranzaksiya başladığı, amma hələ bitirmədiyi dəyişiklikləri görməyəcəksən. Yəni heç kim "xam" informasiyanı oxuya bilməz, hansı ki, dərhal geri qaytarıla bilər.

Bu rejim daha sərt səviyyələrdən (REPEATABLE READ və ya SERIALIZABLE) daha sürətli işləyir, çünki əlavə bloklama və yoxlamalara ehtiyac yoxdur. Yetərincə yüngüldür və eyni zamanda etibarlıdır — məhz buna görə default olaraq istifadə olunur və gündəlik işlərin çoxu üçün idealdır.

Amma o, çirkli oxumanı bloklasa da, READ COMMITTED səni aşağıdakılardan qorumur:

  • "Təkrarlanmayan oxuma" (Non-Repeatable Read): məlumatın dəyəri dəyişə bilər, əgər başqa tranzaksiya sorğular arasında dəyişiklik edərsə.
  • "Fantom oxuma" (Phantom Read): başqa tranzaksiya sənin sorğunun nəticəsinə təsir edən yeni sətrlər əlavə edə bilər.

READ COMMITTED ilə işləyərkən məsləhətlər

Həmişə tranzaksiyanı bitir: COMMIT və ya ROLLBACK istifadə etməyi unutma, yoxsa bloklama problemləri çıxa bilər.

İzolyasiya səviyyəsinin kifayət olduğuna əmin ol: əgər məlumatın tranzaksiya ərzində dəyişməyəcəyinə zəmanət lazımdırsa, REPEATABLE READ-ə bax.

İndekslərdən istifadə et: bu, PostgreSQL-in məlumatı daha tez tapmasına və dəyişiklikləri tətbiq etməsinə kömək edəcək.

Nümunə: sifarişlərin işlənməsi

Tutaq ki, bizdə orders adlı cədvəl var, burada sifarişlər haqqında məlumat saxlanılır:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_name TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending'
);

INSERT INTO orders (customer_name, status)
VALUES ('Alice', 'pending'), ('Bob', 'pending');

"pending" statusunda olan sifarişlərin statusunu yeniləmək istəyirik:

BEGIN;
SELECT * FROM orders WHERE status = 'pending';
UPDATE orders SET status = 'completed' WHERE status = 'pending';
COMMIT;

Əgər bu prosesdə başqa bir tranzaksiya yeni "pending" statuslu sifariş əlavə edib COMMIT edərsə, bizim tranzaksiya bu sətri nəzərə almayacaq, çünki o, oxuma başlayandan sonra əlavə olunub.

Bu, "fantom oxuma" nümunəsidir. Əgər belə hallardan qaçmaq istəyirsənsə, SERIALIZABLE istifadə etməlisən.

READ COMMITTED izolyasiya səviyyəsi əksər verilənlər bazalarında, o cümlədən PostgreSQL-də default seçimdir. O, çirkli oxumalardan qoruyur və standart əməliyyatların çoxu üçün yaxşı seçimdir. Amma daha ciddi konsistentlik tələb olunan hallarda daha sərt izolyasiya səviyyələri lazım ola bilər. Hansı izolyasiya səviyyəsini seçmək isə sənin konkret tapşırıqlarından və performans tələblərindən asılıdır.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION