PDA

View Full Version : مشکل محاسبه موجودی دارو در برنامه داروخانه تحت شبکه



Developer Programmer
چهارشنبه 02 تیر 1389, 19:47 عصر
به اتفاق دوستان داریم اتوماسیون برنامه داروخانه تحت شبکه با دلفی 2010 و SQL Server 2008 رو پیاده سازی میکنیم.

مشکل از این قراره:

1- انبار کلا 5 عدد استامینوفن داره.
2- کاربر A داره نسخه ای رو تایپ میکنه و 5 عدد استامینوفن رو انتخاب میکنه ولی هنوز Save نکرده
3- کاربر B به موجودی انبار نگاه میکنه و 5 عدد استامینوفن رو انتخاب میکنه...در حالیکه قبلا برای A رزور شده بوده.

راهی که ما پیشنهاد کردیم اینه که
1) در هربار انتخاب کاربر A ، همزمان موجودی رو از انبار کم/زیاد کنیم و منتظر ذخیره نشیم. مشکل این کار اینه که Table باز میمونه و ترافیک هم زیاد میشه

2) یه جدول Temp در نظر بگیریم(مثل سبد خرید) هربار که کاربر A اقلام رو انتخاب کرد؛ در جدول ثبت بشه که کاربر A ، تعداد 5 عدد استامینوفن .... حالا کاربر B برای پیدا کردن موجودی واقعی، اول به انبار نگاه میکنه و بعد اون رو از تعداد استامینوفن موجود در جدول Temp کم میکنه...
مشکلش اینه که کاربر A ممکنه ذخیره نکنه و وسط کار برنامه رو ببنده، یا کامپیوترش ریست بشه. در اینصورت داده هایی در Temp هستن که مالک واقعی نداره.

کسی راه حلی به نظرش میرسه؟

hamid-nic
چهارشنبه 02 تیر 1389, 22:49 عصر
برای مشکل زیر

مشکلش اینه که کاربر A ممکنه ذخیره نکنه و وسط کار برنامه رو ببنده، یا کامپیوترش ریست بشه. در اینصورت داده هایی در Temp هستن که مالک واقعی نداره.
فکر کنم بشه این کار را کرد که خصوصیت LockType از شی DataSet خودتون را روی ltBatchOptimistic تنظیم کنید و برای ذخیره تمامی تغییرات بصورت یکجا از متد UpdateBatch استفاده کنید. و برای لغو این کار هم از CancelUpdate استفاده کنید .
البته این یه پیشنهاده مطمئن نیستم که بتونه کامل مشکل تون را حل کنه یا نه .:متفکر:

Developer Programmer
چهارشنبه 02 تیر 1389, 23:21 عصر
فکر کنم بشه این کار را کرد که خصوصیت LockType از شی DataSet خودتون را روی ltBatchOptimistic تنظیم کنید و برای ذخیره تمامی تغییرات بصورت یکجا از متد UpdateBatch استفاده کنید. و برای لغو این کار هم از CancelUpdate استفاده کنید

استفاده از این روش، همون مشکل شماره یک رو بهمراه داره یعنی نمیتونیم منتظر بمونیم که کاربر چیزی رو رزرو نگه داره و بعدش ذخیره کنه.

vcldeveloper
پنج شنبه 03 تیر 1389, 00:30 صبح
البته این یه پیشنهاده مطمئن نیستم که بتونه کامل مشکل تون را حل کنه یا نه .بله، باید از Batch Update استفاده کنه؛ اگر هم چند جدول در این فرآیند دخیل هستند، باید از Transaction استفاده بشه.


استفاده از این روش، همون مشکل شماره یک رو بهمراه داره یعنی نمیتونیم منتظر بمونیم که کاربر چیزی رو رزرو نگه داره و بعدش ذخیره کنه.
وقتی از Batch Update استفاده میکنی، کل نسخه یک جا به بانک ارسال میشه، و در زمانی که کاربر داره نسخه را وارد میکنه، چیزی به بانک نمیره. پس اگر 100 آیتم هم به نسخه اضافه بشه، و ویرایش نسخه هم یک روز طول بکشه، چیزی معطل آن نیست. هر وقت که نسخه آماده شد، کاربر دکمه ثبت را میزنه، و کل نسخه میره برای بانک. اگر مشکلی وجود نداشته باشه، کل نسخه ثبت میشه، اگر مشکلی وجود داشته باشه، بانک مشکل مربوطه را با ذکر اینکه چه رکوردی مشکل ایجاد کرده، به برنامه برگشت میده (مثلا میگه فلان آیتم دیگه وجود نداره). حالا برنامه یا خودش تصمیم میگیره، یا تصمیم گیری رو بر عهده کاربر میزاره (مثلا از کاربر میخواد که به جای اون آیتم، یک داروی معادل بنویسه، یا اون آیتم را از نسخه حذف کنه). اگر مشکل برطرف شد، برنامه میتونه مجددا سعی در ثبت نسخه کنه. اگر مشکل برطرف نشد، برنامه میتونه کلا اون Batch رو Cancel کنه.

اگر چند جدول در حین فرآیند ثبت نسخه تغییر می کنند، عملیات باید در داخل Transaction انجام بشه، تا اگر مشکلی پیش اومد، یا عمل ثبت لغو شد، همه جدول های درگیر به حالت قبل از شروع Transaction برگردند، و اینطوری نشه که بخشی از سفارش ثبت بشه، بخشی دیگه باطل بشه.

Developer Programmer
پنج شنبه 03 تیر 1389, 00:33 صبح
علی جان،
تا اونجایی که من میدونم Batch Update صبر میکنه تا تو کارهات رو بکنی و بعد همه رو یکجا به دیتابیس می فرسته... مثل فاکتور... درسته؟
اگه اینطوری باشه


استفاده از این روش، همون مشکل شماره یک رو بهمراه داره یعنی نمیتونیم منتظر بمونیم که کاربر چیزی رو رزرو نگه داره و بعدش ذخیره کنه.

bootshow
پنج شنبه 03 تیر 1389, 15:01 عصر
1
) در هربار انتخاب کاربر A ، همزمان موجودی رو از انبار کم/زیاد کنیم و منتظر ذخیره نشیم. مشکل این کار اینه که Table باز میمونه و ترافیک هم زیاد میشه
با یه برنامه network monitor مثل net limiter ترافیک شبکتو چک کن.میبینی که در هر لحظه اگر از عکس استفاده نکنی میزان انتقال اطلاعات در حد سرعت dial up هست.تو شبکه که هیچ مشکلی نداره. 5 kb/s . من کل جدولمو با سرعت که اسکرول بکنم حجم انتقال اطلاعات بیشتر از 100 kb/s نمیشه.تازه میتونی جدول و اطلاعاتو فشرده کنی.

از clientdataset و datasetprovider و Datasource و table کنار هم استفاده کن.بعد از انجام تغییرات برای ذخیره باید clientdataset.applyupdate را صدا بزنی تا در صورت ذخیره صحیح اطلاعات ، تمام اطلاعات ذخیره شوند.همون کار transaction را میکنه ولی راحتتره.اگر از table بجای query استفاده کنی فکر کنم تغییرات موقتا روی سرور اعمال بشه.(بخاطر یه مشکل خیلی عجیب وقتی به اینترنت وصل میشم localhost ام خراب میشه.نمیتونم تستش کنم)

vcldeveloper
پنج شنبه 03 تیر 1389, 17:16 عصر
تا اونجایی که من میدونم Batch Update صبر میکنه تا تو کارهات رو بکنی و بعد همه رو یکجا به دیتابیس می فرسته... مثل فاکتور... درسته؟
اگه اینطوری باشه
ببین گزینه یکی که در پست اول بهش اشاره کردی، این رو میگه:

در هربار انتخاب کاربر A ، همزمان موجودی رو از انبار کم/زیاد کنیم و منتظر ذخیره نشیم. مشکل این کار اینه که Table باز میمونه و ترافیک هم زیاد میشه
خب، اینجا من متوجه نمیشم که منظورت از "منتظر ذخیره نشیم" چی هست؛ اما برای بخش دومش که میگی Table باز میمونه، و ترافیک زیاد میشه؛ نه، اینطور نیست. وقتی کاربر داره نسخه را وارد میکنه، نیازی به جدول در سمت سرور نیست. کاربر یک دیتاست به شکل local داره، این دیتاست یک بار موقع لود شدن، داده هایی رو از سرور دریافت کرده، و ارتباطش با سرور قطع شده، پس اتصالی رو به سرور تحمیل نمیکنه. وقتی کاربر نسخه را تکمیل کرد، اتصال به سرور برقرار میشه، داده به سرور ارسال میشه، و دیگه نیازی به اتصال به سرور نیست، و میشه اتصال را بست. پس در حین ورود نسخه، جدولی Lock نمیشه، و سایر کاربران می تونند به راحتی با سرور کار کنند. از نظر ترافیک هم این کار سربار چندانی نداره. ترافیکش با حالتی که رکوردها را تک تک بفرستی، فرق نمیکنه؛ اما فشار روی سرور فرق میکنه. در حالتی که رکوردها را تک تک می فرستی، همه کاربران متصل به سرور که در حال ورود فاکتور هستند، دارند به سرور داده ارسال می کنند، پس سرور داره مرتبا داده دریافت میکنه، و رکوردها و جدول های مختلف را برای انجام اون درخواست ها Lock میکنه. اما وقتی کل درخواست های یک کاربر یک جا ارسال میشه، سرور اکثر اوقات بی کار هست، و فقط زمانی که یک نسخه تکمیل شد، کاری برای انجام داره. در این حالت فشار فقط زمانی هست که تعداد زیادی کاربر بخوان بطور همزمان با هم نسخه هایشان را ارسال کنند. در اون صورت سروری که بیکار بود، در یک لحظه فشار زیادی بهش وارد میشه. خب این حالت هم در عمل احتمال اتفاق افتادنش کم هست، غیر از اینکه تعداد کاربرانت خیلی زیاد باشه، و بخوان از عمد به سرور فشار مضاعف وارد کنند (مثلا حمله DDOS انجام بدند).
در هر حال، این برای SQL Server مشکلی نیست، و این سرور میتونه به راحتی درخواست های ثبت فاکتور را handle کنه، چون نه تعداد کاربرانی که از سرور همزمان استفاده می کنند خیلی بالا ست، و نه داده هایی که می فرستی حجم بالایی دارند.