نمایش نتایج 1 تا 2 از 2

نام تاپیک: آموزش تراکنش کردن در MYSQL

  1. #1

    آموزش تراکنش کردن در MYSQL

    با سلام به دوستان عزیز

    می تونم بگم این تاپیک اولین مقاله آموزشی من توی وب سایت برنامه نویس هست و امیدوارم مقاله مفیدی باشه

    توی نرم افزارهایی که با پول سروکار داره ممکنه حالتهایی پیش بیاد که نیاز هست چندین کوئری بزنیم تا پول رو از حساب یک نفر کم کنیم و به حساب یه نفر دیگه اضافه کنیم. در این حالت کوئری های ما به این صورت می تونه باشه:
    UPDATE `user_mony` SET `mony`=mony-1500000 WHERE (`id`='A')

    UPDATE `user_mony` SET `mony`=mony+1500000 WHERE (`id`='B')


    در حالت عادی این کوئری ها درست کار می کنن ولی فرض کنید کوئری اول رو زدیم و بعد سیستم خاموش شد! یا کوئری اول رو زدیم و قبل از کوئری دوم، کاربر B از سیستم حذف بشه.

    در هر دو حالت 150 هزار تومن به کاربر A ضرر زدیم!

    برای حل این مشکل سیستم ایزالاسیون Isolation Levels طراحی شده که از 4 سطح مختلف تشکیل می شه

    لازم به ذکر هست که این سیستم روی جدول نوع InnoDB اجرا می شه و روی جدولهای نوع MyISAM کاربرد نداره.


    Read uncommitted

    در این حالت تراکنش در حال اجرا می تونه نتیجه تراکنش های انجام نشده رو ببینه! نمی دونم چطور توضیحش بدم، فقط می تونم بگم بهتره این روش رو هیچوقت استفاده نکنید!

    Read committed

    در این حالت تراکنش در حال اجرا می تونه نتیجه های تراکنش های انجام شده رو ببینه و اطلاعاتی که به شما می ده واقعی هستن اما یه مشکل داره و اونم اینکه ردیفهایی که در شرط تراکنش صدق می کنن رو قفل نمی کنه.

    برای توضیح بهتر این مشکل این دو کوئری رو مثال می زنم که مدیر می خواد تعداد کاربرهای طلبکار وب سایت خودش رو بدست بیاره (فرض می کنیم کلا 10 کاربر داریم که مدیر وب سایت باید به اونها پول پرداخت کنه)
    SELECT * FROM `usertb` WHERE (`id`='ok')

    SELECT * FROM `usertb` WHERE (`id`='ok')

    بنظر می رسه که هر دوکوئری باید جواب یکسانی رو برگردونن اما فرض کنید بعد از کوئری اول، یکی از کاربرها حساب کاربری خودش رو حذف می کنه و بعد کوئری دوم اجرا می شه!

    در این حالت نمی دونیم به مدیر بگیم 10 تا کاربر طلبکار داری یا 9 تا! و طبیعتا نمی تونیم مبلغ بدهی وب سایت رو دقیقا مشخص کنیم.

    Repeatable read

    این سطح از ایزولاسیون بر حل مشکل فوق ایجاد شده و در این سطح همه ردیف هایی که در شرط کوئری ها صدق می کنن قفل می شن تا جلوی مشکلاتی که توضیح داده شد گرفته بشه

    در این حالت درسته که ردیفهایی که در شرط صدق می کنن قفل می شن ولی ممکنه بعد از کوئری اول یه کاربر طلبکار جدید به لیست طلبکارها اضافه INSERT بشه و چون تا حالا وجود نداشته طبیعتا نمی شد روش قفل گذاشت!

    به همین دلیل کوئری دوم طلب این کاربر جدید رو محاسبه می کنه و باز هم عددی که به دست میاد با کوئری اول تفاوت داره

    Serializable

    در این حالت علاوه بر قفل شدن ردیفهایی که در شرطها صدق می کنن از INSERT جدید جلوگیری می شه تا اشتباهی پیش نیاد.

    برای اینکه Serializable درست کار کنه باید تراکنش ها رو طوری مرتب کنه که با هم تداخل نداشته باشن و به همین دلیل از وقفه های زمانی استفاده می کنه و به همین دلیل باعث می شه نرم افزار کمی کند بشه اما پایداری داده ها رو تظمین می کنه!

    نکته:

    Read committed ایزولاسیون پیش فرض هست و برای تغییر سطح ایزولاسیون باید از این کوئری استفاده کنیم:

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE


    حالا می تونیم با خیال راحت تراکنش کنیم

    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
    START TRANSACTION
    UPDATE `user_mony` SET `mony`=mony-1500000 WHERE (`id`='A')
    UPDATE `user_mony` SET `mony`=mony+1500000 WHERE (`id`='B')
    COMMIT


    ROLLBACK


    گاهی کار پیچیده می شه و باید چندین کوئری مختلف رو بزنیم و محسابات مختلفی رو انجام بدیم تا تصمیم بگیریم پولی جابجا بشه یا نه

    اگر محاسبات درست بود می تونیم با استفاده از COMMIT تراکنش رو تکمیل کنیم ولی اگر محاسبات اونی که انتظار داشتیم نبود خیلی ساده می تونیم با استفاده از ROLLBACK همه کوئری هایی که توی تراکنش استفاده کردیم رو به حالت قبل برگردونیم

    به این صورت
    if($has_error=='yes'){
    ROLLBACK
    }
    else{
    COMMIT
    }

  2. #2
    کاربر دائمی آواتار فرزند کوروش
    تاریخ عضویت
    مهر 1389
    محل زندگی
    برنامه نویس زندگی هم میکنه؟
    پست
    486

    نقل قول: آموزش تراکنش کردن در MYSQL

    اگه ممکنه يه مثال عملي هم بزن
    ممنون

تاپیک های مشابه

  1. آموزش عوض کردن سرور (جابجایی AD)
    نوشته شده توسط mhjb در بخش شبکه و Networking‌
    پاسخ: 10
    آخرین پست: دوشنبه 22 دی 1393, 14:39 عصر
  2. آموزش Hook کردن توابع API از مبتدی
    نوشته شده توسط crackgns در بخش امنیت در نرم افزار و برنامه نویسی
    پاسخ: 34
    آخرین پست: یک شنبه 02 تیر 1392, 21:04 عصر
  3. آموزش install کردن Kylix در لینوکس
    نوشته شده توسط mamizadeh در بخش برنامه نویسی در Delphi
    پاسخ: 9
    آخرین پست: یک شنبه 26 آذر 1385, 14:28 عصر
  4. درخواست آموزش کامپایل کردن فایلهایdll
    نوشته شده توسط محمد حسن زرین در بخش VB.NET
    پاسخ: 3
    آخرین پست: پنج شنبه 06 مرداد 1384, 12:29 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •