PDA

View Full Version : سوال: همزمانی در مورد خواندن داده ها - فوری



HDDSoft2001
جمعه 20 شهریور 1388, 21:12 عصر
با سلام خدمت تمامی دوستان


دوستان من یک برنامه بیمه بیمارستان رو نوشتم با سی شارپ و اس کیوال 2005 و تحت شبکه (منظور فقط دیتابیس شبکه هست). در ضمن برنامه رو هم بصورت سه لایه و با استورپراسیجر نوشتم و خواندن داده ها هم با دیتا ریدر است و به محض خواندن همه کانکشن رو میبندم.

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

خب حالا دوستان راه حل این قضیه چیست؟ لطفا با کد توضیح دهید

ممنون

arefba
شنبه 21 شهریور 1388, 02:57 صبح
من می تونم یه الگوریتم برات بگم
برای اینکه شماره ی سند به صورت خودکار در تکست باکس نوشته بشه کافیه از یه حلقه استفاده کنی و در قسمت لود بزاری تا هر بار این فرم باز میشه یه شماره بره جلو و اون رو ثبت کنه
با این روش برای تکراری بودن مشکلی پیش نخواد آمد چون هر شماره که بعد از لود صفحه میاد ثبت شده و بار بعد به یه شماره جدید میره

HDDSoft2001
شنبه 21 شهریور 1388, 03:22 صبح
با سلام

در ابتدا تشكر ميكنم از توجه شما.

ببينيد دوستان من براي اين جدول نوع فيلد شماره سند را اتونامبر گذاشتم. درسته زماني كه فرم لود ميشود من يك مقدار (خالي) در جدول درج ميكنم و طبيعتا يك شماره خودكار خود اس كيو ال توليد كيند كه من ان را توي تكس باكس نمايش ميدهم. و اين جوري مشكل كد يونيك حل ميشه!

اما من ميخام كه وقتي يك كاربر دارد با يك شماره سند كار ميكند ان شماره سند قفل شود. و تا زماني كه مراحل ويرايش انجام نشده كاربر ديگري به اين شماره سند دسترسي نداشته باشد همين!

اگه دوستان لطف كنن تيكه كد اون بذارن ممنون ميشم. تو رو خدا دوستان پروژه ام مونده.

با تشكر

alireza_tavakol
شنبه 21 شهریور 1388, 03:32 صبح
من فکر کنم وقتی کاربری داره با یک رکود کار میکنه نباید اون رکورد برای دیگران قفل بشه

ولی اگه شما اصرار به انجام این کار داری می تونی برای هر جدول یک فیلد use در نظر بگیری و مثل یک flag باهاش کار کنی . به عبارت دیگه وقتی یک رکود در حالت ویرایش قرار میگره این فیلد مقدار true میگره و در حالت های عادی مقدار این فیلد false است. حل هر وقتی قرار گزارش بگیری فقط رکورد هایی رو نشون میدی که قرار فیلد use برابر با false است

موفق باشید/

moferferi
شنبه 21 شهریور 1388, 22:28 عصر
من فکر کنم وقتی کاربری داره با یک رکود کار میکنه نباید اون رکورد برای دیگران قفل بشه

ولی اگه شما اصرار به انجام این کار داری می تونی برای هر جدول یک فیلد use در نظر بگیری و مثل یک flag باهاش کار کنی . به عبارت دیگه وقتی یک رکود در حالت ویرایش قرار میگره این فیلد مقدار true میگره و در حالت های عادی مقدار این فیلد false است. حل هر وقتی قرار گزارش بگیری فقط رکورد هایی رو نشون میدی که قرار فیلد use برابر با false است

موفق باشید/
سلام. اقا با عرض شرمندگی روش شما یه مشکلی داره و اونم اینه که اگه ردیفی که true شده باشه (یعنی فلا غیر فعال برای کاربران دیگه) .اگه واسه سیستم فرد مشکلی پیش بیاد و تحت هر شرایطی ارتباط با دیتابیس قطع بشه دیگه اون رکورد FALSE نمیشه و کاربران دیگه تا میاد این مشکل حل بشه یا سر ازش در بیارن کلی وقتشون هدر میره.
به نظر من بهتره موقع اضافه کردن ردیف توی چنین رنامه هایی موقع INSERT کردن برنامه چک کنه شماره مورد نظر هنوز معتبر هست یا خیر.اگه معتبر نبود دوباره یکی به اون مقدار اضافه کنه و شماره جدید را به کاربر نشون بده و ازش سوال کنه ؟
در مورد ویرایش هم بهتره از یه فیلد TIMESTAMP استفاده کرد .چون بعد از هر تغییری این فیلد مقدارش تغییر میکنه.و در قسمت شرط برنامه مقدار این فیلد با یه فیلد دیگه میتونه بهترین کار برای جلوگیری از همزمانی هست.

rahmana
یک شنبه 22 شهریور 1388, 02:06 صبح
با سلام
ببين عزيزم اين مشكل شما توي همه برنامه ها هست
و جوابهايي كه اين دوستانمون دادن درست نيست
شما بايد از يك binding source و table adpterو يك dataset استفاده كني ( البته روشهاي ديگه اي هم داره)
هنگامي كه فرم لود ميشه با استفاده از binding source يك ركورد رزرو ميكني كه ركورد جديدي كه ثبت مي شود با اين شماره ثبت شود اما يك مشكل ديگه هم هست كه شايد تا شما اين فرم را ثبت كردي n نفر ديگه سند ثبت كرده باشند . جواب شما وقتي كه داريد ثبت مي زنيد سيستم چون auto number مي باشد آن عددي كه بايد اختصاص داده شود ثبت مي كند و دوباره براي ركورد بعدي رزرو كردن يك ركورد برا ي دريافت آخرين شماره سند ثبت شده در سيستم و اضافه كردن يك عدد به آن به صورت اتومات توسط سيستم.
اين رزرو ها انجام ميشه ولي تا زماني ثبت نشود در سيستم آن عدد قرار نمي گيرد چون ممكن است در اين مدت چند سند ديگر ثبت شود.
اگه توضيحات بيشتري خواستي در خدمتم
سيد رحمان احمدي
خواستن ، توانستن است.

HDDSoft2001
یک شنبه 22 شهریور 1388, 15:50 عصر
با سلام

ببينيد دوستان ايده خود من اينه كه وقتي فرم لود ميشه برنامه بره يك كورد اضافه كنه و سپس اونو در همان موقع به حالت ويرايش ببره.(در نتيجه كاربر ديگر كه بياد و فرم رو لود كنه يك شماره جديد ميگيره.) در اين موقع ممكن است كه كاربر فرم را كنسل كرده و اصلا ذخيره نكند كه مهم نيست چون بعدا اونو ويرايش ميكنه.

سوال من اينه كه ميخام كس ديگه اي وقتي يه كاربر مشغول است بر روي يه سند كاربر ديگه اجازه دسترسي به اونو نداشته باشه.

سناريوي كه من فقط بهش فكر كردم اينه كه بيام يه فيلد به جدول اضافه كنم و زماني كه كاربري بخواهد به فلان شماره سند (ركورد) دسترسي داشته باشد (اولين كاربر) بيايد و ساعت سيستم را توي اين فيلد بريزد و زماني كه كارش (ويرايش) را انجام داد اين فيلد را خالي كند. در اين لحظه كه اين كاربر دارد با اين ركورد كار ميكند اگر كاربر ديگري بخواهد به همين ركورد دسترسي داشته باشد بيايد و اين ساعت درج شده در اين فيلد را با ساعت سيستم چك كند اگر ببيند كه اگر زمان سيستم با زمان درج شده در اين فيلد مثلا 10 دقيقه بيشتر است (يه زمان قرارداي) يا فيلد خالي هست بيايد و حق دسترسي را به دست گيرد و زمان جديد را ثبت كند.

معايب :
1- زمان دسترسي محدود مي باشد. چون ممكن است كار كاربر بيشتر از اين زمان طول بكشد و بعد از وارد كردن كلي اطلاعات سيستم بيايد و پيغام بدهد كه كاربر ديگري در حال استفاده است.
2- مديريت پيچيده
3- نگراني براي وجود مشكل براي سيستم كلاينت كه براش اتفاقي بيافتد نيست كه مثلا فلان فيلد را false نكند.
ولي دوستان ميخام بدونم با قفل ها جطوري بايد كار كرد چون من اصلا كار نكردم.
در مورد binding source هم من تا به حال كار نكردم. (با ويزاردها خيلي كم كار ميكنم) اگر ميشه منو راهنمايي كنيد و يه تكه كد بذاريد همرا با عملكردش.

خيلي ممنون

HDDSoft2001
دوشنبه 23 شهریور 1388, 19:20 عصر
با سلام

دوستان كسي نيست كه كار با قفل ها را بلد باشه. :متفکر:

دوستان اگه كسي هست بگه خدا وكيلي خيلي كارم گيره. :ناراحت:

meysam_pro
دوشنبه 23 شهریور 1388, 21:15 عصر
اگر سیستم تون قسمت مالی یا امنیتی داره، شما باید یه جدولی واسه Log داشتین(همون مدیریت Session) خب این جدول حتما شامل فیلد های :

id,logDate,logTime,workType,workOnTable,userId خواهد بود(این جدول برای کارهای دیتابیسی هستش نه واسه برنامه! من این دو تا رو جدا در نظر میگیرم).
خب حالا شما میتونیدیک جدول پایه واسه workType داشته باشید(مثل : شروع ویرایش سند، پایان ویرایش سند، بروز شدن سند و.....)و الان براحتی میتونید کوئری دلخواهتون رو از این جدول بکشید.
چون سیستم تون داده هاش خیلی مهمه توصیه میشه بیشتر از این باید Log درست کنید(از طریق تریگر و ...)
البته یه کم بیشتر رو دیتابیس کار کنید حتما به این نتیجه خواهید رسید که این محدودیت ها رو دیتابیس بزارید(از طریق Trigger و Constriant و Transaction isolation level و...)

مشکل: ممکنه بگید اگه سیستم یه مشکلی واسش پیش بیاد و به صورت abnormal بره بیرون اونوت لاگ درست شده ناقص میشه ، ولی خب می تونید با نوشتن یک کوئری که آیا userId کارش رو به صورت پیش بینی شده تموم کرده یا نه کنترل کنید و همچنین یک رکورد به لاگ خطاهای نرم افزار تون اضافه کنید.

HDDSoft2001
دوشنبه 23 شهریور 1388, 23:40 عصر
با سلام

خيلي ممنونم از اين راه كارتون. به نظرم من هم ايده خوبي هست. ولي اگه ميشه يه خرده جزئي تر ميگفتيد با يك مثال بهتر متوجه ميشدم. (چون ذهن منو به جاهاي ديگه كشونديد. مثل گفتن " از طریق Trigger و Constriant و Transaction isolation level و... " و ...)

راستي يه سوال ديگه اينه كه اين جدول لاگ رو كي ركودهاشو پاك كنم. به عنوان مثال زماني كه كار به درستي انجام شد.
يا يه گزينه برا پاك كردن بذارم و يا خودم هر چند وقت اين كارو بكنم و يا ... .

بازم ممنون از جوابتون.

راستي دوستان يه نظر درباره روش پيشنهادي خودم هم اگه ميشه بدهند.

با تشكر از همه

HDDSoft2001
سه شنبه 24 شهریور 1388, 13:10 عصر
با سلام

دوست عزیزم اگر مثلا یه رکورد با این روش شما قفل بشه ایا باید محدودیت زمانی برای اون قائل شد. چون ممکن است کاربر یا واقعا کارش طول بکشد و بخواهد تا هر زمان این رکورد رو قفل کنه و از طرف دیگه ممکن است ارتباطش قطع شود و نتواند لاگ را کامل کند (ثبت پایان ویرایش در لاگ).

برای اینکار من یه پیشنهاد دارم و اونم اینه که ابتدا یه فیلد دیگه به نام شماره کلایت به جدول لاگ اضافه کنیم و زمانی که میخاهیم کاری بکنیم شماره کلاینت رو توی اون درج کنیم (فکر کنم خود اس کیو ال تابع دارد) و موقعی که بخواهد قفل رو بگیریم یه کوئری بگیریم که اگر قفل ازاد نبود و کلاینتی که قفل گذاشته هنوز ایا فعال است یا خیر (به جای محدویت زمانی) (برای اینکه ممکن است کانکشن کلاینت به صورت غیرنرمال قطع شده باشد) اگر کلاینت فعال نبود در این صورت متوجه میشیم که قفل را باید بدست گرفت.

دوست عزیز نمدونم نظرات درسته یا نه اگه میشه بازم راهنماییم کنید به صورت جزئی تر چون خودتون این کارو تو عمل دیدید.

meysam_pro
سه شنبه 24 شهریور 1388, 16:22 عصر
ولي اگه ميشه يه خرده جزئي تر ميگفتيد با يك مثال بهتر ...
خب جدول رو که گفتم ، کارها رو هم خودتون دسته بندی کنید(تو جدول پایه مثلا :شروع ویرایش سند، پایان ویرایش سند، بروز شدن سند و....)


جدول لاگ رو كي ركودهاشو پاك كنم؟
قرار نیست پاک بشه! شما از این ها استفاده خواهید کرد. البته اگر هم بخواهید پاک کنید از طریق job ها در SQL میتونید روزانه یا هفتگی پاکش کنید.




ذهن منو به جاهاي ديگه كشونديد. مثل گفتن " از طریق Trigger و Constriant و Transaction isolation level و...
واسه کل جدول هاتون تریگر عملیات بزارین تا اگه یکی اومد دستی پاک کرد تشخیص بدید(سیستم های مالی و امنیتی خیلی حساس اند، باید خیلی تله پیش بینی کنید).


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


برای اینکار من یه پیشنهاد دارم و اونم اینه که ابتدا یه فیلد دیگه به نام شماره کلایت به جدول لاگ ...
نه دیگه شماره یا اسم کلاینت با نام یا کد کاربر یکی نیست، یه بار دیگه رو پست های گفته شده دقت بفرمایید.