با استفاده از دستور 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 استفاده می‌شود.

توسط پژوهشگر در 201 روز قبل ساعت 03:27
دسته بندی ها: SQL SQL for beginner
sara در 201 روز قبل ساعت 06:22

برای انتقال امن وجه بین دو ردیف در جدول 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 را در پایان صادر کنید و به احتمال بن‌بست و اثرات ناسازگار تراکنش‌ها فکر کنید.

گزارش

1 پاسخ

جدید ترین قدیمی ترین بالاترین امتیاز پاسخ های من

در حال بارگیری...
ورود به حساب کاربری