با استفاده از دستور LOCK TABLES یک انتقال امن وجه بین دو ردیف در جدول accounts (ستونهای id و balance) پیادهسازی کنید طوری که در حین اجرای عملیات هیچ فرایند دیگری نتواند موجودی حسابها را تغییر دهد
2.0 بازدید آخرین ویرایش در 201 روز قبل ساعت 03:27 0.0
برای حل مسئله ابتدا جدول accounts را با WRITE lock قفل کنید (LOCK TABLES accounts WRITE)، سپس مانده حساب فرستنده را خوانده و در صورت کافی بودن وجه، با دو دستور UPDATE مقدار را از حساب فرستنده کسر و به حساب گیرنده اضافه کنید و در پایان با UNLOCK TABLES قفل را آزاد کنید. نکتهها: LOCK TABLES سطح جدول را قفل میکند و با تراکنشهای فعال ناسازگار است (در MySQL باعث COMMIT ضمنی میشود)، بنابراین برای نمونهسازی از MyISAM یا با آگاهی از رفتار implicit commit استفاده کنید؛ در عمل برای رفتار دقیقتر و قفلگذاری ردیفی ترجیحاً از InnoDB و START TRANSACTION با SELECT ... FOR UPDATE استفاده میشود.
1 پاسخ
جدید ترین قدیمی ترین بالاترین امتیاز پاسخ های من
در حال بارگیری...
برای ارسال پاسخ باید با حساب کاربری وارد شوید.
ورود به حساب کاربری
برای انتقال امن وجه بین دو ردیف در جدول accounts میتوانید از LOCK TABLES استفاده کرده و با LOCK TABLES accounts WRITE، قفل جدول را تا پایان عملیات حفظ کنید تا هیچ فرایندی موجودی را تغییر ندهد. با این حال این قفل سطح جدول است و با تراکنشهای فعال ناسازگار است (و در MySQL ممکن است باعث COMMIT ضمنی شود)، بنابراین معمولاً توصیه میشود از InnoDB با START TRANSACTION و SELECT ... FOR UPDATE استفاده کنید تا قفل ردیفی و رفتار همزمانی دقیقتری داشت. در پیادهسازی با InnoDB، تراکنش را با START TRANSACTION آغاز کرده، دو ردیف فرستنده و گیرنده را با SELECT ... FOR UPDATE قفل کنید، موجودی را در صورت کفایت کسر و به گیرنده اضافه کنید و تراکنش را با COMMIT پایان دهید تا عملیات به طور اتمی انجام شود. در صورت استفاده از LOCK TABLES، فراموش نکنید UNLOCK TABLES را در پایان صادر کنید و به احتمال بنبست و اثرات ناسازگار تراکنشها فکر کنید.
گزارش