YIi da ma’lumotlar bazasi tranzaksiyalari bilan ishlash

Ma’lumotlar bazasi bilan ishlayotganimizda ba’zida ma'lumotlar bazasiga bir vaqtning o’zida minglab so’rov yuborishga to’g’ri keladi. Bugun men shu holatga duch keldim. Ya’ni, jadvaldagi bir ustundagi ma’lumotga murojat qilib, undagi qiymatni mos xolda kerakli qiymatga o’zgartirishga to’g’ri keldi. Jadvaldagi qatorlar soni 2000 dan ortiqroq. Dastlab quidagi usulni ishlatib ko’rdim:
$model=UserMeta::model()->findAll();
    foreach($model as $v){
        UserMeta::model()->updateByPk($v->id,array("seat_date"=>"1111-11-11"));
    }

Natijada quidagi xato chiqdi:
Fatal error: Maximum execution time of 30 seconds exceeded in ...

Bu xato ko'pchilik web-dasturchilarga ma'lum. Sabab, bajarilayotgan kodni bajarilish vaqti ko’payib ketganida. Buni php.ini faylidan uzaytirib qo’yish mummkin lekin muammoni hal qilmaydi. Chunki, siklda 2000 ta so’rov yuborilyapdi va bu uzoq vaqt oladi. Buni hal qilish uchun ma'lumotlar bazasi tranzaksiyalaridan foydalanamiz.

Tranzaksiyadan foydalanish
Ma’lumotlar bazasida tranzaksiya tushunchasi MB bilan operatsiyalarning mantiqiy birligi bo’lib – ma’lumotlarni o’qish yoki “update” qilish uchun foydalanuvchi tomonidan yuborilgan so’rovlarni “bir butun” bajarishidir.
Tranzaksiya jarayonini quidagi 4 bosqichga bo'lish mumkin:
  • Tranzaksiyani boshlash
  • So’rovlarni birma-bir bajarish. Bunda bazadagi o'zgarishlar ko'rinmaydi.
  • Transaksiyani tasdiqlash(commit). Agar tranzaksiya muvaffaqiyatli tugasa, o’zgarishlarni ko’rish mumkin.
  • Agar bir so’rov xato bo’lsa, butun tranzaksiya to’xtaydi
Yuqoridagi ketma-ketlikni kod orqali quidagica yozish mumkin:
$model = User::model()->findAll();
$connection = Yii::app()->db;
$transaction = $connection->beginTransaction();
try {
    foreach ($model as $v) {
        $sql = "update user_meta set seat_date='2222222' where id='".$v->id."'";
        $connection->createCommand($sql)->execute();
    }
$transaction->commit();
        } catch (Exception $e) {  // agar so’rov xato bo’lsa, exceptionga keladi
            $transaction->rollBack();
        }

Yuqoridagi kodni bajarishga atigi 2-3 soniya vaqt ketdi.

6 комментариев

s_nazirov
$model2=UserMeta::model()->findByPk($v->id);
$model2->seat_date="1111-11-11";
$model2->save();


yuqorida ishlatilgan kodni o'rniga
UserMeta::model()->updateByPk($v->id,array("seat_date"=>"1111-11-11"))

ishlatish yaxshiroq va qisqarog
0
sarvar_uz
rahmat, yuqoridagi kodni o'zgartirib qo'ydim
0
mageUz
Bunday qilsachi?
$ids=array();
foreach ($model as $v) $ids[]=$v->id;
$sql = "update user_meta set seat_date='2222222' where id in (".implode(',',$ids).")";
$connection->createCommand($sql)->execute();
1
s_nazirov
yaxshi fikir ammo bunaqa sql zapros bajaraliyotganda tranzaksiya ishlatish shart deb o'ylayman
0
ulugbek
Nimani hisobiga tranzaksiya tez ishlaydi?
0
UmarDeveloper
Bilishim bo`yicha tranzaksiya ishni tezlashtiradi degan tushuncha noto`g`ri. Tranzaksiyaning ma`lum yo`naltirilgan vazifasi bor. Tasavur qilaylik ikkita modelimiz bor har biriga ma`lumot tushishi shart. Bir modelga ma`lumot tushib ikkinchisiga tushmi qolishi bu xato. Sistema noto`g`ri ishlashiga olib keladi. Bir modelga mal`umot tushirsagu save bo`lsa ikkinchi modelga ma`lumot tushirib save qila olmasak (saqlashda qandaydir xatolik bo`lsa) shunday holatda birinchi modeldagi save ni bekor qilish uchun tranzaksiya ishlatiladi. Ya`ni qaysidir bir jadvalda saqlash yoki o`zgartirishlar amalga oshmay qolsa qilingan oldingi ishlarni ortga qaytarishda ishlatiladi.
0