-Sig‘im chegarasidan ortiq ro‘yxatdan o‘tish muammolarini hal qilish uchun parallellikni boshqarish va amalga oshirish jarayoni-
1. Asosiy ma’lumotlar: birinchi kelgan — birinchi xizmat ko‘rsatiladi tamoyili asosidagi kursga ro‘yxatdan o‘tishda sig‘imdan ortiq yozilish
Onlayn ma’ruzalar va ta’lim platformalari ko‘pincha muayyan kurslar sig‘imini cheklaydi va birinchi kelgan — birinchi xizmat ko‘rsatiladi tamoyili asosidagi ro‘yxatdan o‘tish tizimidan foydalanadi. Masalan, sig‘im 100 ta bo‘lsa, ro‘yxatdan o‘tish 100-arizachigacha qabul qilinishi, undan keyingi so‘rovlar esa yopilishi kerak.
Oddiy sharoitlarda buni ro‘yxatdan o‘tgan talabalar sonini tekshirish va agar son sig‘imdan kam bo‘lsa, ro‘yxatdan o‘tishni saqlash orqali amalga oshirish mumkin. Biroq bir nechta foydalanuvchi deyarli bir vaqtda ro‘yxatdan o‘tganda muammo yuzaga keladi. Agar sig‘im 100 ta, joriy son esa 99 ta bo‘lsa, bir vaqtdagi ikkita so‘rov ham 99 sonini o‘qib, muvaffaqiyatli ro‘yxatdan o‘tishi mumkin. Natijada yakuniy talabalar soni 101 taga yetadi.
Bu bir nechta tranzaksiya bir xil ma’lumotni bir vaqtda o‘qib, o‘zgartirganda yuzaga keladigan parallellik muammosidir. Shu sababli faqat oddiy CRUD mantiqi yordamida sig‘im chegarasi kabi biznes qoidasiga ishonchli tarzda kafolat berish qiyin.
2. Oddiy amalga oshirishning cheklovlari
Eng oson amalga oshirish usuli — joriy talabalar sonini tekshirish, sig‘imni nazorat qilish va keyin ro‘yxatdan o‘tishni saqlash.
@Transactional
public void enroll(Long courseId, Long studentId) {
Course course = courseRepository.findById(courseId)
.orElseThrow();
if (course.getCurrentCount() >= course.getCapacity()) {
throw new IllegalStateException("Course is full.");
}
course.increaseCount();
enrollmentRepository.save(new Enrollment(courseId, studentId));
}
Bu koddagi muammo shundaki, bir nechta so‘rov bir xil currentCount qiymatini o‘qib, shartdan bir vaqtda o‘tishi mumkin. @Transactional qo‘llanilishi tranzaksiyalar o‘rtasidagi bir vaqtdagi kirishni avtomatik ravishda bloklamaydi. Shu sababli alohida parallellik nazorati talab etiladi.
3. Parallellikni hal qilish usullarini taqqoslash
3.1 synchronized
synchronized bitta JVM ichida bir xil kodning bir vaqtda bajarilishining oldini olishi mumkin. Biroq server bir nechta instansiyaga kengaytirilganda, har bir server alohida JVM’dan foydalanadi va shu sababli serverlar o‘rtasidagi parallellikni boshqara olmaydi. Shuning uchun u taqsimlangan muhitlar uchun mos emas.
3.2 Pessimistik blokirovka
Pessimistik blokirovka ma’lumotlar bazasidagi qatorni bloklaydi, so‘ng ro‘yxatdan o‘tgan talabalar sonini tekshiradi va yangilaydi. JPA’da PESSIMISTIC_WRITE’dan foydalanish mumkin.
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select c from Course c where c.id = :id")
Optional<Course> findByIdForUpdate(@Param("id") Long id);
U bir nechta serverlarda ishlash afzalligiga ega bo‘lsa-da, muayyan kursga so‘rovlar to‘planib qolganda blokirovkani kutayotgan so‘rovlar soni ortishi mumkin.
3.3 Optimistik blokirovka
Optimistik blokirovka boshqa tranzaksiya ma’lumotlarni o‘zgartirgan yoki o‘zgartirmaganini tekshirish uchun versiya ma’lumotlaridan foydalanadi.
@Version
private Long version;
To‘qnashuv yuz berganda istisno yuzaga kelgani sababli, qayta urinish kabi qo‘shimcha ishlov berish talab etiladi. Birinchi kelgan — birinchi xizmat ko‘rsatiladi tamoyili asosidagi ro‘yxatdan o‘tishda bo‘lgani kabi, to‘qnashuvlar qisqa vaqt ichida to‘planadigan vaziyatlarda qayta urinish siyosatini ham hisobga olish kerak.
4. Yakuniy tanlov: shartli atomar UPDATE
Bu muammo uchun ma’lumotlar bazasining shartli atomar UPDATE yondashuvini tanladik. Joriy sonni so‘rab, qarorni ilovada qabul qilish o‘rniga, bu yondashuv sig‘im shartini UPDATE operatorining o‘ziga kiritadi.
UPDATE course
SET current_count = current_count + 1
WHERE id = :courseId
AND current_count < capacity;
Asosiy jihat — shartni tekshirish va qiymatni o‘zgartirishni ma’lumotlar bazasining yagona operatsiyasi sifatida qayta ishlash. Agar sig‘im mavjud bo‘lsa, UPDATE muvaffaqiyatli bajariladi. Sig‘imga erishilgach, keyingi so‘rovlar WHERE shartiga mos kelmaydi va ta’sirlangan qatorlar soni 0 ga teng bo‘ladi.
Ilova ta’sirlangan qatorlar sonini tekshirish orqali operatsiya muvaffaqiyatli bajarilganini aniqlashi mumkin.
@Transactional
public void enroll(Long courseId, Long studentId) {
int updated = courseRepository.increaseCountIfAvailable(courseId);
if (updated == 0) {
throw new IllegalStateException("Course is full.");
}
enrollmentRepository.save(
Enrollment.create(courseId, studentId)
);
}
Spring Data JPA’da shartli UPDATE’ni @Modifying va @Query yordamida aniqlash mumkin.
@Modifying
@Query("update Course c " +
"set c.currentCount = c.currentCount + 1 " +
"where c.id = :courseId " +
"and c.currentCount < c.capacity")
int increaseCountIfAvailable(@Param("courseId") Long courseId);
5. Nima uchun bu yondashuv tanlandi
Eng muhim mezon biznes qoidasidagi sig‘im chegarasini ma’lumotlar bazasi darajasida kafolatlash mumkin yoki mumkin emasligi edi. synchronized ko‘p serverli muhitda cheklovlarga ega, optimistik blokirovka esa to‘qnashuvlar tez-tez yuz berganda qayta urinish mantiqini talab qiladi. Pessimistik blokirovka ishonchli, ammo muayyan kursga so‘rovlar to‘planib qolganda blokirovka uchun raqobat yuzaga kelishi mumkin.
Shartli atomar UPDATE sig‘imni tekshirish va ro‘yxatdan o‘tgan talabalar sonini oshirishni yagona operatsiyaga birlashtirishi mumkin. Yana bir afzalligi shundaki, alohida taqsimlangan blokirovka tizimini qo‘shmasdan, mavjud ma’lumotlar bazasi funksiyalaridan foydalanish mumkin. Joriy talab kabi miqdorni oddiy oshirish muammosi uchun bu nisbatan ixcham yechimdir.
6. Takroriy ro‘yxatdan o‘tishlar va ma’lumotlar yaxlitligi
Sig‘imdan ortiq yozilishning oldi olingan taqdirda ham, bir talabaning takroriy ro‘yxatdan o‘tishiga alohida yo‘l qo‘ymaslik kerak. Tez-tez tugma bosilishi yoki tarmoq orqali so‘rovning qayta yuborilishi sababli bir xil so‘rov takrorlanishi mumkin. Shu sababli talaba va kurs kombinatsiyasiga unique cheklovini qo‘yish eng xavfsiz usuldir.
ALTER TABLE enrollment
ADD CONSTRAINT uk_enrollment_student_course
UNIQUE (student_id, course_id);
Bundan tashqari, sig‘imni oshirish va ro‘yxatdan o‘tish yozuvini kiritish yagona tranzaksiya doirasida qayta ishlanishi kerak. Xatolik yuz berganda ikki operatsiyani birgalikda muvaffaqiyatli bajariladigan yoki birgalikda bekor qilinadigan qilib sozlash sig‘im oshib, ro‘yxatdan o‘tish saqlanmay qolishi muammosining oldini oladi.
7. Amalga oshirish natijalari
Parallellik nazoratini qo‘llash tadbir boshlanganidan keyin darhol so‘rovlar to‘planib qolganida ham sig‘imdan ortiq yozilishning oldini olishi mumkin. Atomar ma’lumotlar bazasi operatsiyalaridan foydalanilgani sababli, bir xil sig‘im qoidasi bir nechta ilova serverlari ishlayotgan muhitlarda ham qo‘llanilishi mumkin.
Yana bir afzalligi shundaki, alohida taqsimlangan blokirovka tizimi talab qilinmagani uchun infratuzilma murakkabligi sezilarli darajada oshmaydi. So‘rov yuborish, qaror qabul qilish va saqlash jarayonini qisqartirish mumkinligi sababli kod ham soddalashadi. Biroq tashqi to‘lovlar yoki xabarlarni nashr etish jarayoni ishtirok etsa, alohida tranzaksiya va hodisalarni qayta ishlash strategiyalarini ko‘rib chiqish kerak.
8. Xulosa
Birinchi kelgan — birinchi xizmat ko‘rsatiladi tamoyili asosidagi kursga ro‘yxatdan o‘tishda sig‘imdan ortiq yozilish muammosi odatiy, bitta so‘rovli qayta ishlash vaqtida oson ko‘zga tashlanmaydi, ammo ma’lum bir vaqtda so‘rovlar to‘planishi bilan darhol namoyon bo‘ladi. Joriy sonni shunchaki so‘rab, uning sig‘imdan kamligini tekshirish orqali bir nechta so‘rovni xavfsiz qayta ishlash qiyin.
Bu muammo uchun bir nechta yondashuvni taqqosladik va shartli atomar UPDATE’ni tanladik. Buning sababi — u sig‘imni tekshirish va ro‘yxatdan o‘tgan talabalar sonini oshirishni yagona ma’lumotlar bazasi operatsiyasi sifatida qayta ishlash orqali sig‘imdan ortiq yozilishning oldini oladi hamda bir nechta serverli muhitlarda izchil natijalar beradi. Unique cheklovi va tranzaksiyani birgalikda qo‘llash takroriy ro‘yxatdan o‘tishlar va ma’lumotlar nomuvofiqligining oldini ham oladi.
Oxir-oqibat, parallellik muammolarini hal qilishning kaliti bir vaqtda qaysi ma’lumotlar o‘zgartirilishi mumkinligini, qaysi biznes qoidalariga rioya qilinishi kerakligini va bu qoidalar qaysi qatlamda kafolatlanishi lozimligini aniq belgilashdan iborat. Bu nuqtayi nazar sig‘im, zaxira, kupon miqdori va o‘rinlar kabi cheklangan resurslarni bir vaqtda band qiladigan funksiyalar uchun ayniqsa muhimdir.
dwmoon