Tranzaksiya nima ? (Siz bilmagan ma’lumotlar)

Habibov Ulug'bek
5 min readJan 11, 2025

--

Assalamu Alaykum bugun Relational databazalarda tranzaksiyani ko`rib chiqamiz. U nimaga kerakligidan tortib bazi databazalarda qanday implimentatsiya qilinganini ham bilib olamiz.

Tranzaksiya jarayoni

Note: Bu maqola pul o`tkazmalaridagi tranzaksiya haqida emas.

Tranzaksiya nima ?

Tranzaksiya bu bir necha SQL so`rovlari birgalikda bir butun bajariladigan ish deb qaraladigan so`rov .Bir butun bajariladigan ish deb qarashga asosiy sabab bu SQL databazalarning asosiy qoidasi bu ma’lumotlar aniq bir structurada bo`lishi va shu sababli sizda juda ko`p jadvallar bo`lishi mumkin va ularning barchasini bir so`rov orqali o`zgartirib bo`lmaydi va bunda bizga tranzaksiya yordam beradi .Tranzaksiyaga bir vaqtda bajarilishi kerak bo`lgan mantiqiy amallar to`plami deb qarasak bo`ladi .

Masalan siz mehmonxonadan bir xona buyurtma qilmoqchisiz siz xonani tanlaysiz va buyurtmani bosasiz va sizga karta ma;lumotlarini kirgizadigan oyna chiqib keladi to`ldirgandan so`ng to`lash tugmasi bosilganda backenda so`rov ketadi shu paytda biz xonani database orqali bo`shligini tekshirishimiz agarda bo`sh bo`lsa kartadan pulni yetish yetmasligi tekshirilib yetkan holatda , yechib xonani ushbu odam nomiga buyurtma qilishimiz kerak ammo ungacha xona buyurtma bo`lsa pul yechilmay qolishi kerak bu ammallarni hammasi to`g`ri va umumiy bir ishdek ishlatish uchun tranzaksiya qo`llaniladi .

Tranzaksiya nimalardan iborat ?

Tranzaksiya uch qismdan iborat BEGIN kalit so`zi bu tranzaksiya boshlanganini bildiradi ,hamma o`zgarishlar amalga oshirilgandan so`ng COMMIT kalit so`zi orqali ularni databazaga joylaymiz. Bazan natijalar biz xohlagandek bo`lmasligi mumkin va bu holatda hamma narsani oldingisiga qaytarish uchun ROLLBACK kalit so`zidan foydalaniladi.

Tepadagi misol kodini ko`rib chiqamiz :

BEGIN;

-- 1-Qadam : Xona bo`shligini tekshirish
SELECT room_id
FROM rooms
WHERE room_id = 101 AND status = 'available'
FOR UPDATE;

-- 2-Qadam: Kartada kerakli miqdorda pul borligini tekshirish
SELECT card_balance
FROM guests
WHERE guest_id = 1
FOR UPDATE;

-- Xona narxini 500 deb qabul qilamiz
IF (SELECT card_balance FROM guests WHERE guest_id = 1) >= 500 THEN

-- 3-Qadam: Pulni yechib olish
UPDATE guests
SET card_balance = card_balance - 500
WHERE guest_id = 1;

-- 4-Qadam: Tarixga buyurtmani qo`shish
INSERT INTO bookings (guest_id, room_id, check_in_date, check_out_date, booking_date, amount_paid)
VALUES (1, 101, '2025-01-10', '2025-01-15', CURRENT_DATE, 500);

-- 5-Qadam: Xona holatini buyurtmalanganga o`tkazish
UPDATE rooms
SET status = 'booked'
WHERE room_id = 101;

-- Tranzaksiyani databazaga yuklash
COMMIT;

ELSE
-- kartada yetarli pul bo`lmasa hamma narsani orqaga qaytarish
ROLLBACK;
RAISE EXCEPTION 'Kerakli miqdorda pul mavjud emas.';
END IF;

Ana endi shu yerda to`xtaymiz va COMMIT hamda ROLLBACK databazalarda qanday implimentatsiya qilinganini ko`rib chiqamiz.

Davomini o`qishdan oldin o`zingiz uchun bu qanday bo`lishi mumkinligini o`ylab ko`ring balkim siz yaxshiroq yo`lni toparsiz.

Commit va Rollback databaselarda odatda 2 xil yo`l bilan amalga oshirilgan :

1-yo`l .Hamma o`zgarishlarni xotiraga(buffer pool)ga yozib borish va commit jarayonida hamma o`zgarishlarni birdaniga databazaga kiritish.
Bu holatda har bir query tez amalga oshishi mumkin yani update, delete lar chunki ular xotirada bo`lmoqda ammo ularni birdaniga databazaga yozish ko`p vaqt talab qilishi va bu ko`pincha databaza crash bo`lishiga olib keladi.

2- yo`l . Har bir query databazaga to`g`ridan tog`ri yozib boriladi Bu holatda har bir query 1-yo`ldagidan sekinroq bo`ladi chunki u dbga to`gridan to`gri yozmoqda .Ammo hamma narsa biror narx evaziga keladi. Agarda siz rollback qilmoqchi bo`lsangiz databazadagi har bir ma`lumotni oldingi holatiga qaytarishingiz kerak va bu vaqt talab qiladi. Tepadagi yo`lda esa hamma narsani bufferdan o`chirib yuborish esa buni oddiy hal qiladi .

Bu aytilgan yo`llardagi tezlik butun umumiy tranzaksiya jarayoniga tegishli emas . Masalan 1000 querylik tranzaksiya amalga oshirilmoqda bu ikki xil yo`lda ham bir xil vaqtda tugashi mumkin. Ammo 1-yo`lda u har bir queryni tugatishga 1 sekund va ularni birgalikda db ga yozishga 10 sekund, umumiy 1010 sekund sarflaydi. 2-yo`lda esa hamma bir queryga 1.01 sekundan sarflaydi va tepadagi yo`ldan query bo`yicha sekinroq ammo tugash vaqti bir xil bo`ladi. (Bir xil bo`lmasligi ham mumkin meni buni misol sifatida keltirdim tushunish osonroq bo`lishi uchun).

Bu yerda sizda qo`shimcha savol bo`lishi mumkin , agarda commit qilish jarayonida databaza ishlashdan to`xtasa nima bo`ladi (crash) ?

Xo’sh databazalar xuddi shu muammolarni oldini olish uchun, taranzaksiya davomida ushbu ishni amalga oshirda :
Databazaga biror o`zgarish kiritishdan oldin , tranzaksiya malumotlari to`liq transaction log ga yozib boriladi. Bu PostgreSQL WAL (Write-Ahead Logging) deb ataladi .

Commit qismi ham 2 qismdan iborat va u Two-Phase Commit deb ataladi .

  1. Prepare Phase(Tayyorlash qismi ):
  • Tranzaksiya tayyorlanadi va hamma narsa transaction logga yoziladi .
  • Bu holatda hali tranzaksiya tugatilgan deb hisoblanilmaydi.
  1. Commit Phase(Ma’lumotni o`zgartirish qismi) :
  • Bu holatda transaction logga tugatildi deb o`zgartirish kiritiladi va o`zgarishlar databaza tomonidan malumotlar o`zgartiriladi.

Bu yerda crash bo`lgani uchun 2 holat bor :
Agarda u Prepare Phaseda bo`lsa ammo commit qilinmagan bo`lsa bu holda databasa restart olgandan so`ng transaction logni tekshiradi va unga asoslanib tranzaksiyani rollback qiladi. Agarda u Commited Phaseda bo`lsa transaction logga qarab ma’lumotlarni o`zgartirib chiqadi .Restart har xil databaseda har bo`ladi . Mysql/sqlserver databazalari tranzaksiya to`li rollback qilinmaguncha ishga tushmaydi .Postgresda esa tranzaksiya topilib rollback qilinish boshlanadi yangilari shunchaki ularni hisobga olmay ketishadi, qolib ketgan ma’lumotlar Vacuum orqali o`chirib yuboriladi.

Tranzaksiyada amalga oshirilgan amallar boshqalarga darhol ko`rinadimi ?
Odatda yo`q chunki ular hali commit qilinmagan va bu xuddi jadvalga ma’lumotlar yozilgan holatda bo`lsa ham commited colum false bo’ladi va buni boshqalar ko`ra olmaydi. Ammo bu uni to`liq ko`rib bo`lmaydi degani emas bu tranzaksiyani amalga oshirayotgan user o`zgarishlarni ko`ra oladi . Hamda bu yana isolation levelga bog`liq bu haqida keyingi maqolalarda gaplashamiz.

Biz bilamizku tranzaksiya odatda ma’lumotni yangilash yoki o`zgartirish uchun ishlatilinadi ammo bazan ular Read only tranzaksiyalar ham bo`lishi mumkin . Bu nimaga kerak bu aynan o`sha vaqtda ma’lumotlar bo`yicha report kerak bo’lsa va bu holatda bizga tranzaksiyaning snapshot qobilyati juda qo`l keladi va yangi o`zgarishlar reportdan chetda qolib ketadi .Snapshot bizga dataBazaning aynan o`sha vaqtda nusxasi hisoblanadi.

Note : Tranzaksiya hamma amallari bir databaza ulanishida bo`lishi zarur , siz bir ulanishda(connection) boshlab 2 chisida tugata olmaysiz.

Note: Biz qilayotgan oddiy amallar ham databaza tomonidan tranzaksiyaga o`raladi har doim va u ko`p holatlarda avtomatik commitda turadi .

Xulosa qilib aytadigan bo`lsak tranzaksiya bizga databazadagi ma’lumotlar biz xohlamagan tarzada o`zgarib ketishini oldini olishga yordam beradigan va databazalar tominidan berilgan yordam.

Agarda maqola yoqqan bo`lsa chapak chaling (ko`p chalsayam bo`ladi 50 tagacha).

Xato va kamchiliklar uchun uzr !!!

linkedin.com => Ulug’bek Habibov | LinkedIn

telegram channel => @habibov_ulugbek

--

--

Habibov Ulug'bek
Habibov Ulug'bek

Written by Habibov Ulug'bek

Software Engineer | Backend Nodejs Developer

No responses yet