PDA

View Full Version : سوال: همزمانی در ورود و ثبت دیتا در دیتابیس



IMANAZADI
سه شنبه 28 مهر 1394, 10:20 صبح
با سلام
فرض کنید داریم یک سیستم ورود اطلاعات طراحی میکنیم


شرح به این صورته


یک سری نقشه داریم که شماره نقشه یونیک می باشد
هر نقشه یکسری اطلاعات داره


من یک صفحه طراحی کردم که کاربر میاد اطلاعات نقشه براساس شماره نقشه ایی که انتخاب کرده در فرم مربوطه وارد میکنه و بعد با کلیک کردن save ، اطلاعات وارد شده ، توسط آژاکس ارسال و در دیتابیس ذخیره میشه


حالا اگر دو تا کاربر همزمان یک نقشه رو بازکنن جهت ورود اطلاعات ، اطلاعات تکراری ثبت میشه و مشکلات دیگه
چطوری میشه از همزمانی ورود اطلاعات نقشه توسط دو یا چند کاربر جلوگیری کرد ؟؟؟؟

Unique
سه شنبه 28 مهر 1394, 21:08 عصر
حالا اگر دو تا کاربر همزمان یک نقشه رو بازکنن جهت ورود اطلاعات ، اطلاعات تکراری ثبت میشه و مشکلات دیگه
خیر این مشکل در صورت رعایت نکاتی پیش نمیاد.

اگه شماره فیلد شماره نقشه را به عنوان فیلد کلید اصلی و منحصر به فرد توی mysql تعریف کنی ، حتی اگه هر دو با هم ارسال بشن غیر ممکنه mysql به دیلیل یکتا بودن فیدل شماره نقشه هر دو را insert کنه و یکی از کاربران خطای duplicate میگیره.

اگه هم دلت نمیخواد فیلد شماره نقشه را منحصر به فرد و کلید اصلی معرفی کنی میتونی به عناون یک فیلد عادی ایجاد کنی و با lock کردن جدول مانع بشی مقادیر تکراری توی جدول insert بشه. اما همون استفاده از فیلد کلید اصلی و منحصر به فرد بهترین گزنه هست به نظر من. در زمان خطا هم به کاربر میگی قبلا کسی اطلاعات این نقشه را وارد کرده.

us1234
سه شنبه 28 مهر 1394, 22:07 عصر
روشی که Unique گفت اصولی هست

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

IMANAZADI
چهارشنبه 29 مهر 1394, 05:39 صبح
فکر کنم طرح مسئله رو بد مطرح کردم

ببنید یک جدول داریم شامل شماره نقشه که این شماره نقشه کلید اصلی هست

حالا یک جدول دیگه داریم شامل فیلدهای ای دی شماره نقشه ، متریال ، وزن ، و ....

حالا در جدول دوم ، هر نقشه میتونه متریال تکراری داشته باشه مثلا نقشه 001 میتونه متریال b رو 2 بار یا بیشتر داشته باشه

در نتیجه در جدول دوم ما نمیتونم چیزی رو uniqe index کنیم

واسه این مسئله چیزی که به ذهن خودم میرسه اینه که یک فیلد به جدول اول که شماره نقشه ها هست اضافه کنم و وقتی هر کاربری اونو انتخاب کرد برای data entry اون فیلد مقدار 1 بگیره و زمانیکه کاربر

دومی خواست اون شماره نقشه رو دیتا کنه اول فیلد رو بخونه اگه 0 بود اجازه دیتا بده در غیر اینصورت اجازه دسترسی نده ، تا زمانیکه کاربر اول خارج شد از اون صفحه فیلد مقدار 0 بگیره

البته اینجاهم یکم مشکل داره مثلا زمانیکه برق بره اون فیلد همیشه 1 میمونه :اشتباه::متفکر:

بنظرتون واسه این مشکل چه راه کاری موجود هست ؟؟؟

سایت هایی که نفرات آنلاین رو نشون میدن از همین تکنیک استفاده میکنن (البته اگه اشتباه نکنم)

ولی اگه برق بره اون نفر همیشه آنلاین نشون داده میشه ، این مشکل رو چطوری برطرف میکنن ؟

us1234
چهارشنبه 29 مهر 1394, 07:36 صبح
فکر کنم طرح مسئله رو بد مطرح کردم

ببنید یک جدول داریم شامل شماره نقشه که این شماره نقشه کلید اصلی هست

حالا یک جدول دیگه داریم شامل فیلدهای ای دی شماره نقشه ، متریال ، وزن ، و ....

حالا در جدول دوم ، هر نقشه میتونه متریال تکراری داشته باشه مثلا نقشه 001 میتونه متریال b رو 2 بار یا بیشتر داشته باشه

در نتیجه در جدول دوم ما نمیتونم چیزی رو uniqe index کنیم

واسه این مسئله چیزی که به ذهن خودم میرسه اینه که یک فیلد به جدول اول که شماره نقشه ها هست اضافه کنم و وقتی هر کاربری اونو انتخاب کرد برای data entry اون فیلد مقدار 1 بگیره و زمانیکه کاربر

دومی خواست اون شماره نقشه رو دیتا کنه اول فیلد رو بخونه اگه 0 بود اجازه دیتا بده در غیر اینصورت اجازه دسترسی نده ، تا زمانیکه کاربر اول خارج شد از اون صفحه فیلد مقدار 0 بگیره

البته اینجاهم یکم مشکل داره مثلا زمانیکه برق بره اون فیلد همیشه 1 میمونه :اشتباه::متفکر:

بنظرتون واسه این مشکل چه راه کاری موجود هست ؟؟؟

سایت هایی که نفرات آنلاین رو نشون میدن از همین تکنیک استفاده میکنن (البته اگه اشتباه نکنم)

ولی اگه برق بره اون نفر همیشه آنلاین نشون داده میشه ، این مشکل رو چطوری برطرف میکنن ؟

2 راه به ذهنم میرسه
اول اینکه با جاوا اسکریپت در قسمت کاربر یک ایجکس درست کنید که هر چند دقیقه وضیعت باز بودن مرورگر کاربر را به سایت اعلام کنه ... ( فکر نکنم لزومی به این کار باشه راه دوم : )

راه دوم هم کلا وقتی یک کاربر در سایت عملیاتی انجام میده ( مثلا باز کردن یک صفحه یا ... ) زمان آخرین عملیات را ذخیره کنید و هر چند دقیقه ( مثلا 30 دقیقه ) یکبار زمان های آخرین حضور کاربر را بررسی کنید اگر در این مدت کاری انجام نداده بود یعنی کاربر آنلاین نیست .

IMANAZADI
چهارشنبه 29 مهر 1394, 10:22 صبح
راه دوم هم کلا وقتی یک کاربر در سایت عملیاتی انجام میده ( مثلا باز کردن یک صفحه یا ... ) زمان آخرین عملیات را ذخیره کنید و هر چند دقیقه ( مثلا 30 دقیقه ) یکبار زمان های آخرین حضور کاربر را بررسی کنید اگر در این مدت کاری انجام نداده بود یعنی کاربر آنلاین نیست .


خوب اگر یک یوزری آنلاین بود ولی اکشنی در صفحه نداشت چی !!؟؟ اینطوری آفلاین به حساب میاد

Unique
چهارشنبه 29 مهر 1394, 13:42 عصر
آقا ایمان شما مباحث را داری بیخودی بزرگ میکنی :

برای توضیح نیاز به اسم و موجودیت دارم :
۱ - جدولی به نام maps داریم که هر ردیفش یک نقشه مثلا با شماره و نام (و شاید فیلد های دیگه) هست که هر رکورد منحصر به یک نقشه به عنوان موجودیت هست
۲ - جدولی به نام mapsinfo داریم که برای هر نقشه از جدول maps رکورد هایی مرتبطی داریم.

اما تشریح :

در مورد جدول maps که شماره نقشه فیلد یکتا هست و کلید اصلی هیچوقت کسی نمیتونه دو تا نقشه با شماره یکسان ایجاد یا حتی ویرایش کنه ، خود database مانع میشه.
من متوجه نمیشم توی جدول mpasinfo شما دقیقا میخواین مانع از چی بشین !؟ میخوان مانع بشین رکورد جدید با یکسان بودن همه فیلد ها با رکورد دیگه ای ثبت یا ویرایش بشه ؟
اگه اینطوری هست خوب کاری ندریه ، وقتی میخواین insert یا update کنین اول جدول را LOCK WRITE میکنید و یک Query میزنید ببینین چنین رکوردی معاول مقادیر جدید ثبتی یا ویرایشی وجود داره یا نه ،‌ اگه نداشت که Insert یا update را انجام میدین و از LOCK میاین بیرون. اگه هم داشت اخطار میدین که رکورد مشابهی قبلا ثبت شده.

اگه میخواین خیلی دقیقا براتون تشریح کنم فیلد ها را مشخص و مقدار بدین و مثال بزنین و بگین چه اتفاقی نباید بیفته تا توضیح بدم.
این ایجاد فیلد جدید و 1 و 0 دادن و اینا اصلا روش خوبی نیست. با lock کردن جداول و ایجاد unique key برای یک یا چند فیلد بسته به شرایط میشه مانع از تداخل شد.

us1234
چهارشنبه 29 مهر 1394, 14:59 عصر
آقا ایمان شما مباحث را داری بیخودی بزرگ میکنی :

برای توضیح نیاز به اسم و موجودیت دارم :
۱ - جدولی به نام maps داریم که هر ردیفش یک نقشه مثلا با شماره و نام (و شاید فیلد های دیگه) هست که هر رکورد منحصر به یک نقشه به عنوان موجودیت هست
۲ - جدولی به نام mapsinfo داریم که برای هر نقشه از جدول maps رکورد هایی مرتبطی داریم.

اما تشریح :

در مورد جدول maps که شماره نقشه فیلد یکتا هست و کلید اصلی هیچوقت کسی نمیتونه دو تا نقشه با شماره یکسان ایجاد یا حتی ویرایش کنه ، خود database مانع میشه.
من متوجه نمیشم توی جدول mpasinfo شما دقیقا میخواین مانع از چی بشین !؟ میخوان مانع بشین رکورد جدید با یکسان بودن همه فیلد ها با رکورد دیگه ای ثبت یا ویرایش بشه ؟
اگه اینطوری هست خوب کاری ندریه ، وقتی میخواین insert یا update کنین اول جدول را LOCK WRITE میکنید و یک Query میزنید ببینین چنین رکوردی معاول مقادیر جدید ثبتی یا ویرایشی وجود داره یا نه ،‌ اگه نداشت که Insert یا update را انجام میدین و از LOCK میاین بیرون. اگه هم داشت اخطار میدین که رکورد مشابهی قبلا ثبت شده.

اگه میخواین خیلی دقیقا براتون تشریح کنم فیلد ها را مشخص و مقدار بدین و مثال بزنین و بگین چه اتفاقی نباید بیفته تا توضیح بدم.
این ایجاد فیلد جدید و 1 و 0 دادن و اینا اصلا روش خوبی نیست. با lock کردن جداول و ایجاد unique key برای یک یا چند فیلد بسته به شرایط میشه مانع از تداخل شد.

دقیق متوجه منظور استارتر نشدم ولی فکر میکنم مشکل ایشان در زمانی است که چند نفر همزمان روی یک سطر تغییرات ایجاد میکنند .

مثلا یک سطر داریم که یکی از فیلد های آن نال است ، شخص اول تصمیم میگیره این فیلد 3 باشه و شخص دیگری تصمیم میگره این فیلد 4 باشه وقتی این 2 نفر همزمان بخواهند روی این سطر کار کنند ، ویرایش یکی از آنها از بین میره و عملا آخرین ادیت ذخیره شده است . ( شاید هر 2 شخص هم درست گفته باشه ولی برای کاربران تناقض پیش میاد که فیلدی که من ادیت کردم را چرا شخص دیگری بعد از من ادیت کرده ! )

در چین مواردی به نظر من باید وقتی سطر برای ادیت باز شد به کاربر های دیگه اجازه ادیت سطر داده نشود ...

IMANAZADI
چهارشنبه 29 مهر 1394, 16:10 عصر
آقا ایمان شما مباحث را داری بیخودی بزرگ میکنی :

برای توضیح نیاز به اسم و موجودیت دارم :
۱ - جدولی به نام maps داریم که هر ردیفش یک نقشه مثلا با شماره و نام (و شاید فیلد های دیگه) هست که هر رکورد منحصر به یک نقشه به عنوان موجودیت هست
۲ - جدولی به نام mapsinfo داریم که برای هر نقشه از جدول maps رکورد هایی مرتبطی داریم.

اما تشریح :

در مورد جدول maps که شماره نقشه فیلد یکتا هست و کلید اصلی هیچوقت کسی نمیتونه دو تا نقشه با شماره یکسان ایجاد یا حتی ویرایش کنه ، خود database مانع میشه.
من متوجه نمیشم توی جدول mpasinfo شما دقیقا میخواین مانع از چی بشین !؟ میخوان مانع بشین رکورد جدید با یکسان بودن همه فیلد ها با رکورد دیگه ای ثبت یا ویرایش بشه ؟
اگه اینطوری هست خوب کاری ندریه ، وقتی میخواین insert یا update کنین اول جدول را LOCK WRITE میکنید و یک Query میزنید ببینین چنین رکوردی معاول مقادیر جدید ثبتی یا ویرایشی وجود داره یا نه ،‌ اگه نداشت که Insert یا update را انجام میدین و از LOCK میاین بیرون. اگه هم داشت اخطار میدین که رکورد مشابهی قبلا ثبت شده.

اگه میخواین خیلی دقیقا براتون تشریح کنم فیلد ها را مشخص و مقدار بدین و مثال بزنین و بگین چه اتفاقی نباید بیفته تا توضیح بدم.
این ایجاد فیلد جدید و 1 و 0 دادن و اینا اصلا روش خوبی نیست. با lock کردن جداول و ایجاد unique key برای یک یا چند فیلد بسته به شرایط میشه مانع از تداخل شد.


ببنید یک جدول داریم به نام map شامل فیلد شماره نقشه ، که شماره نقشه کلید اصلی و یونیک هستش که کسی هم نمیتونه شماره نقشه تکراری ثبت کنه

یک جدول دیگه داریم به نام map_info شامل فیلدهای آی دی ، کلید شماره نقشه از جدول map ، کد متریال ، نام متریال ، مقدار ، وزن

نکته : ما در جدول دوم اطلاعات تکراری داریم یعنی یک نقشه میتونه یک کد متریال رو چند بار در یک نقشه با نام و مقدار و وزن یکسان داشته باشه

حالا سناریو چیه

نقشه (منظور نقشه کاغذی هست نه فایل و ...) توسط کارفرما ارسال میشه به پیمانکار(که مثلا ما هستیم)

یکی مسئول ثبت شماره نقشه های ارسالی در جدول maps می باشه (فقط شماره نقشه ها)

بعد از ثبت اصل نقشه ها ارسالی بین کاربران جهت data entry پخش میشه

هر کاربر با توجه نقشه ایی که دستش هست شماره نقشه رو از توی کمبوباکس که شماره نقشه ها هست(کمبو از جدول map پر میشه) انتخاب میکنه و اطلاعات اونو وارد میکنه( در جدول دوم)

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

امیدوارم گرفته باشید دیگه نمیدونم چه طوری توضیح بدم:اشتباه:

Unique
جمعه 01 آبان 1394, 01:00 صبح
مثلا یک سطر داریم که یکی از فیلد های آن نال است ، شخص اول تصمیم میگیره این فیلد 3 باشه و شخص دیگری تصمیم میگره این فیلد 4 باشه وقتی این 2 نفر همزمان بخواهند روی این سطر کار کنند ، ویرایش یکی از آنها از بین میره و عملا آخرین ادیت ذخیره شده است . ( شاید هر 2 شخص هم درست گفته باشه ولی برای کاربران تناقض پیش میاد که فیلدی که من ادیت کردم را چرا شخص دیگری بعد از من ادیت کرده ! )

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


در چین مواردی به نظر من باید وقتی سطر برای ادیت باز شد به کاربر های دیگه اجازه ادیت سطر داده نشود ...
ممکنه اتفاق اصلا ۵ دقیقه اینطرف و اون طرف بیفته ! حالا حتما مهم نیست همزمان بشه و وقتی کاربر دوباره check میکنه ممکنه براش سوال بشه من که اینو ۲ زده بودم و حالا چرا ۳ شده ! فرقی با حالت قبلی نداره و بیخودی لقمه را چرخونیدم.


امیدوارم گرفته باشید دیگه نمیدونم چه طوری توضیح بدم
با کمال ادب و احترام بد توضیح میدین !


نکته : ما در جدول دوم اطلاعات تکراری داریم یعنی یک نقشه میتونه یک کد متریال رو چند بار در یک نقشه با نام و مقدار و وزن یکسان داشته باشه
جملتون مشکل داره و دارین علنا میگین جدول دوم میتونه چندین رکورد دقیقا مشابه به هم داشته باشه که خوب duplicate record ثبت میشه. احتمالا منظورتون یکی از این دو حالته :
۱ - ما در جدول دوم اطلاعات تکراری داریم یعنی یک نقشه میتونه چند رکورد با کد متریال های غیر یکسان با نام و مقدار و وزن یکسان داشته باشه
2 - ما در جدول دوم اطلاعات تکراری داریم یعنی یک نقشه میتونه یک کد متریال رو چند بار توی رکورد های مختلف در یک نقشه با نام و مقدار و وزن غیر یکسان داشته باشه


حالا اگر یک نقشه رو دو تا کاربر به طور اتفاقی تکراری داشته باشن و بطور همزمان بخوان اطلاعات اونو وارد کنن(insert) مشکل پیش میاد
حالا اصلا جدا از توضیحات بالا چون دارین میگین تکراری یعنی کدمتریال و نام متریال و مقدار و وزن برای اون کد نقشه قبلا توی سایت ثبت شده ،‌ توجه داشته باشین اگه جدول را قبل از Insert یا update قفل کنید حتی اگه ۲ یا چند درخواست دقیقا همزمان ارسال بشن میرن توی صف و یکی قطعا قبل از دیگری اتفاق میفته ! خوب بعد از قفل کردن و قبل از Insert یا update اول یک select میگیریم ببینیم این رکورد قبلا (حتی ۱ میلی ثانیه قبل از lock کردن ما که توی صف بودیم) ثبت شده یا نه و اگه ثبت شده بود اخطار میدیم که این قبلا ثبت شده و شما دارین اطلاعات تکراری ثبت میکنین. همونطور هم که برای us1234 توضیح دادم میتونین نام کاربر و زمان ثبت را هم توی رکورد ثبت کنین تا بتونین پیگیری کنین نقشه وقعا دست طرف بوده یا نه !

موفق باشین.