رتبه موضوع:
  • 1 رای - 5 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
مشکل تعداد موجودی انبار و سبد خرید
#1
سلام دوستان
فرض کنید من از یک کالا 20 عدد دارم و توی سبد خرید کاربر A همه این کالا هارو انتخاب می کنه یعنی همون 20 تا و منم تعداد درخواستی رو چک کردم و مشکلی نبوده و حالا آماده ارسال به بانک هستم
توی همین موقع یه کاربر دیگه هم دقیقا همچین درخواستی داره، مقدار درخواستی با موجودی انبار چک می شه و درسته آماده ارسال به بانک
اگه من هردوتا رو بفرستم به بانک خوب 40 تا کالا فروختم در حالی که فقط 20 تا توی انبار هست
مشکلاتی از این قبیل رو چطوری می شه حل کرد؟


ممنون
no pain, no gain
پاسخ
تشکر شده توسط:
#2
بهش میگن تراکنش یا transction در Mysql . سرچ بزنید آموزش ها زیاده. خلاصه کار اینه که کار وقتی شروع شده و هنوز کامل تموم نشده mysql یا هر دیتابیس دیگه شما، یک سری اطلاعاتی رو موقتا نگه میداره. یعنی شما وقتی کاربر اول شروع کرد به پرداخت مثلا تعداد انبار رو 20 تا کم میکنی . حالا اگر پرداختش کامل شد که تراکنش با موفقیت انجام میشه اگر نشد اون 20 تایی که واسش رزرو کردی برمیگرده به موجودی انبار.
پاسخ
تشکر شده توسط:
#3
خب ممکنه همون لحظه کاربر مرورگر رو ببنده، mysql از کجا میفهمه باید rollback کنه؟
پاسخ
تشکر شده توسط:
#4
(17-03-1394، 11:43 ب.ظ)php نوشته: بهش میگن تراکنش یا transction در Mysql . سرچ بزنید آموزش ها زیاده. خلاصه کار اینه که کار وقتی شروع شده و هنوز کامل تموم نشده mysql یا هر دیتابیس دیگه شما، یک سری اطلاعاتی رو موقتا نگه میداره. یعنی شما وقتی کاربر اول شروع کرد به پرداخت مثلا تعداد انبار رو 20 تا کم میکنی . حالا اگر پرداختش کامل شد که تراکنش با موفقیت انجام میشه اگر نشد اون 20 تایی که واسش رزرو کردی برمیگرده به موجودی انبار.
می خواستم همین کار رو کنم و هر یک دقیقه چک کنم اونایی رو که 10 دقیقه هست از ارسال به بانکشون گذشته ولی پرداخت ناموفق بوده به هردلیلی رو برگردونه سرجاشون
برای این کار می خوام از cron job استفاده کنم که هر یک دقیقه اجرا بشه ولی اجرای cron job هر یک دقیقه منطقیه؟ فشار نمیاره؟
no pain, no gain
پاسخ
تشکر شده توسط:
#5
اگه اسکریپتتون کوتاه باشه و در عرض یکی دو ثانیه جواب بده، اجراش مانعی نداره.
پاسخ
تشکر شده توسط:
#6
مستقیم با بانک در ارتباطه
کل سطر ها رو چک می کنه (تعداد سطرها به مشتری ها بستگی داره) اگه هر سطر تایمش از 10 دقیقه گشده بود از اونجا حذف می کنه و به موجودی انبار اضافه می کنه
یعنی در کل تو بدترین حالت :
1. select
2. delete
3. insert

البته اگه اینا رو توی foreach و ... ننویستم و به صورت batch insert, bache delete و ... عمل کنم فکر نکنم خیلی روی کارایی تاثیر بذاره و زمان بگیره
no pain, no gain
پاسخ
تشکر شده توسط:
#7
دقیقاً همینطوره. حتی میشه مواردی مثل صف و... رو در سیستمهای شلوغ پیاده سازی کرد. مثلاً رکوردهایی که باید پردازش بشن، توی یک جدول pending اطلاعات خاصی مثل id و... رو ذخیره کنید و بعد از پردازش، از اونجا حذف و به جدول processed منتقل کنید (یا اگه به آمارش نیاز ندارین، حذف کنید).
پاسخ
تشکر شده توسط:
#8
درواقع در دنیای واقعی هم همینگونه است.

مثلا شما وارد یک فروشگاه لوازم خانگی می شوید و قصد خرید یک تلویزیونی دارید که فقط یکی از آن در مغازه موجود است و شما به مغازه دار می گویید من این تلویزیون را می خواهم و مغازه دار روی صندلی میشنه و خودکار را بر میداره و میخواهد شروع کند برای فاکتور نوشتن در این میان یک مشتری دیگری میاد اون تلویزیون را می خواهد ولی مغازه دار میگه ایشون از شما زود تر اومدن(تراکنش) و می خواهن بخرن اگر ایشون پسند نکردن من به شما میفروشم(حذف فاکتور مشتری اول طی یک زمانی) که اگر مشتری اول نتونه خرید کنه قطعا به مشتری دوم فروخته میشه ولی در دنیای مجازی اینطوری است چرا که در دنیای واقعی بیانه ایی و ... میزارند. البته اینجا یک ایده جالب دیگه در اومد اونم گرفتن بیانه. البته این ایده باید رویش کار شود و کلی گفتم.
پاسخ
تشکر شده توسط:
#9
بنظر من روش منطقی اینه که وقتی مشتری پول رو واقعاً داد، کالا رو بهش بدین. حالا ممکنه یکی توی درگاه بانکی 1 دقیقه ای پرداخت کنه یکی 9 دقیقه معطل کنه. حق با اونیه که زودتر پول رو داده. پس شما باید وقتی خرید انجام شد و از درگاه به سایتتون برگشتین، موجودی رو کم کنید و اگه موجودی قابل کم شدن نبود (یکی دیگه زودتر خریده بود)، پیغام عذرخواهی نشون بدین و بگین پولتون برگشت میخوره و یک لاگ برای اینکار ثبت کنید که مدیر خبردار بشه (یا حتی به مدیر SMS بدین). درگاههای بانکی مستقیم (نه واسط) اکثراً متد settle هم دارن که تا وقتی صداش نزنید، تراکنش بعد از مدت مشخصی (معمولاً 20 تا 45 دقیقه) برگشت میخوره. میتونید از این هم کمک بگیرین. مثلاً اگه تونستین موجودی رو کم کنین، settle رو صدا بزنید وگرنه تراکنش بطور خودکار برگشت خواهد خورد.
پاسخ
تشکر شده توسط: __undercover
#10
(18-03-1394، 12:14 ب.ظ)ADMIN نوشته: بنظر من روش منطقی اینه که وقتی مشتری پول رو واقعاً داد، کالا رو بهش بدین. حالا ممکنه یکی توی درگاه بانکی 1 دقیقه ای پرداخت کنه یکی 9 دقیقه معطل کنه. حق با اونیه که زودتر پول رو داده. پس شما باید وقتی خرید انجام شد و از درگاه به سایتتون برگشتین، موجودی رو کم کنید و اگه موجودی قابل کم شدن نبود (یکی دیگه زودتر خریده بود)، پیغام عذرخواهی نشون بدین و بگین پولتون برگشت میخوره و یک لاگ برای اینکار ثبت کنید که مدیر خبردار بشه (یا حتی به مدیر SMS بدین). درگاههای بانکی مستقیم (نه واسط) اکثراً متد settle هم دارن که تا وقتی صداش نزنید، تراکنش بعد از مدت مشخصی (معمولاً 20 تا 45 دقیقه) برگشت میخوره. میتونید از این هم کمک بگیرین. مثلاً اگه تونستین موجودی رو کم کنین، settle رو صدا بزنید وگرنه تراکنش بطور خودکار برگشت خواهد خورد.

بهترین راه همینه، مثلا برای تراکنش های درگاه سامان تا verify نکنی پول برگشت میخوره! دیگ cron job هم لازم نیست.
پاسخ
تشکر شده توسط:
#11
این خوبه ولی بیشتر برای موقع ای که یک نوع کالا انتخاب شده
توی سبد خرید چندین نوع کالا می تونه وجود داشته باشه و این مشکل شاید فقط برای یکی یا تعدادی از کالاها به وجود بیاد
پول بقیه هم باید پس بدیم و مشتری زده می شه ...
no pain, no gain
پاسخ
تشکر شده توسط:
#12
(17-03-1394، 11:43 ب.ظ)php نوشته: بهش میگن تراکنش یا transction در Mysql . سرچ بزنید آموزش ها زیاده. خلاصه کار اینه که کار وقتی شروع شده و هنوز کامل تموم نشده mysql یا هر دیتابیس دیگه شما، یک سری اطلاعاتی رو موقتا نگه میداره. یعنی شما وقتی کاربر اول شروع کرد به پرداخت مثلا تعداد انبار رو 20 تا کم میکنی . حالا اگر پرداختش کامل شد که تراکنش با موفقیت انجام میشه اگر نشد اون 20 تایی که واسش رزرو کردی برمیگرده به موجودی انبار.


ترکنشهای پایگاه داده این طور نیست که یک تراکنش رو شروع کنید و بعدا مثلا 10 دقیقه بعد رولبک کنی یا کمیت!!!
تراکنش ها نوعی قفل روی داده هست که باید با یک عملیات بسیار کوتاه انجام بشه و بیشتر برای عملیات مالی استفاده میشه و نه انبار و ...!

شما می تونید یک فیلد در کنار موجودی داشته باشید برای کالاهای موجود در سبد و در لیست فروش، یعنی اگر 10 کالا دارید، با سفارش یک کاربر، یکی کم میشه از کل تعداد موجودی و یکی به در لیست فروش اضافه میشه، همچنین اطلاعات کالا در سبد هم منعکس میشه برای سبدهای انصراف داده شده یا رها شده، حالا برای کاربر دوم 9 کالا نمایش داده میشه مثلا، اگر کاربر اول خرید رو انجام داد، به تعداد خریدی که کرده از فیلد در لیست فروش کم میشه، اگر انصراف داد، از لیست فروش کم میشه و به موجودی اضافه میشه و اگر خرید رو وسط راه رها کرد، می تونید با کرانجاب و ... بیاید، سبدهای رها شده در مثلا 24 ساعت گذشته رو حذف کنید و فیلد موجودی و لیست فروش رو بروز کنید.

البته الان نمایش تعداد موجودی در سایت مرسوم نیست و جنبه روانی داره و کسی اینکار رو نمی کنه و همین که با سفارش و رفتن کالا در لیست فروش، موجودی صفر بشه، می زنند ناموجود!
پاسخ
تشکر شده توسط: php
#13
(18-03-1394، 01:24 ب.ظ)desatir7316 نوشته: این خوبه ولی بیشتر برای موقع ای که یک نوع کالا انتخاب شده
توی سبد خرید چندین نوع کالا می تونه وجود داشته باشه و این مشکل شاید فقط برای یکی یا تعدادی از کالاها به وجود بیاد
پول بقیه هم باید پس بدیم و مشتری زده می شه ...

دقیقا. منم با روش آقای admin مخالفم چرا که فاکتور برای چندین محصول سفارش داده میشه

ولی درکل اینطور مشکلات برای فروشگاه های پر فروش پیش میاد.
پاسخ
تشکر شده توسط:
#14
خوب یک روش دیگه میتونه این باشه که شما یک جدول دارین به اسم Reserved که توش فیلدهای product_id و quantity دارین و کالاها رو وقتی کاربر میخواد به درگاه بانکی منتقل بشه، بعد از کم شدن موجودی، توی این جدول همراه با Timestamp خرید ثبت میکنید و اگه خرید انجام شد، از اینجا حذف میکنید و اگه نشد، با Cron Jobs در فواصل زمانی مشخص (مثلاً هر یک دقیقه) توی این جدول هر رکوردی بیشتر از زمان مشخص (مثلاً 15 دقیقه) از Timestamp خریدش گذشته بود، حذف کرده و تعداد رو دوباره به موجودی اضافه میکنید. این روش عملیه ولی مشکلی که داره (که راه خاصی هم براش عملاً نیست) اینه که ممکنه از این روش یکی سوء استفاده کنه و بیاد تمام محصولات شما رو توی وضعیت Reserved ببره و عملاً فروشگاه شما از کار بیفته تا 15 دقیقه و اگه یه روبات برای اینکار بنویسه، کلاً میتونه همیشه فروشگاه شما رو خالی نشون بده. برای جلوگیری از این مسائل میشه راهکارهایی مثل الزام برای عضویت قبل از خرید (زیاد مناسب برخی فروشگاهها نیست) یا کد امنیتی قبل از پرداخت و... رو قرار داد.
پاسخ
تشکر شده توسط: sm_pakdel
#15
(19-03-1394، 01:11 ق.ظ)ADMIN نوشته: خوب یک روش دیگه میتونه این باشه که شما یک جدول دارین به اسم Reserved که توش فیلدهای product_id و quantity دارین و کالاها رو وقتی کاربر میخواد به درگاه بانکی منتقل بشه، بعد از کم شدن موجودی، توی این جدول همراه با Timestamp خرید ثبت میکنید و اگه خرید انجام شد، از اینجا حذف میکنید و اگه نشد، با Cron Jobs در فواصل زمانی مشخص (مثلاً هر یک دقیقه) توی این جدول هر رکوردی بیشتر از زمان مشخص (مثلاً 15 دقیقه) از Timestamp خریدش گذشته بود، حذف کرده و تعداد رو دوباره به موجودی اضافه میکنید. این روش عملیه ولی مشکلی که داره (که راه خاصی هم براش عملاً نیست) اینه که ممکنه از این روش یکی سوء استفاده کنه و بیاد تمام محصولات شما رو توی وضعیت Reserved ببره و عملاً فروشگاه شما از کار بیفته تا 15 دقیقه و اگه یه روبات برای اینکار بنویسه، کلاً میتونه همیشه فروشگاه شما رو خالی نشون بده. برای جلوگیری از این مسائل میشه راهکارهایی مثل الزام برای عضویت قبل از خرید (زیاد مناسب برخی فروشگاهها نیست) یا کد امنیتی قبل از پرداخت و... رو قرار داد.

توی این روش اگه ادمین دستی تعداد کالاهارو کم کنه تکلیف چیست؟ فرض کنید ادمین تعداد رو کرده 2 بعد ما بعده 1 دیقه دوباره اونو کردیم 3، اونوقت اگه یکی 3 تا سفارش بده باید بهش زنگ بزنیم بگیم شرمنده موجودی ندازیم!!!
پاسخ
تشکر شده توسط:




کاربران در حال بازدید این موضوع: 1 مهمان