PDA

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



aminbin
سه شنبه 23 آبان 1396, 09:55 صبح
با سلام. من از EF در سایتم استفاده میکنم. در یکی از جدولها ، یک فیلد کلید دارم که نباید auto-increment باشه چون بعدا ممکنه بخوام تغییرش بدم. در نتیجه راهکار رو در این دیدم که موقع ثبت ، بالاترین مقدار این فیلد رو در جدول پیدا کنم و یک مقدار اضافه کنم و رکورد رو با اون کلید ذخیره کنم. الان مشکلی که فکر میکنم وجود داشته باشه این هست که اگه در یک لحظه دو تا کاربر همزمان بخوان ثبت کنن، اونموقع فکر میکنم مقدار Id یکسان براشون در نظر گرفته بشه. خواهشا اگر راهکاری برای این مشکل دارید لطفا مطرح بفرمایید.

debugger
سه شنبه 23 آبان 1396, 10:05 صبح
دوست عزیز اشتباه بزرگ شما اینه که کلید اصلی auto-increment ندارید . دیتابیس را دوباره تحلیل و انالیز کنید .

aminbin
سه شنبه 23 آبان 1396, 10:30 صبح
دوست عزیز اشتباه بزرگ شما اینه که کلید اصلی auto-increment ندارید . دیتابیس را دوباره تحلیل و انالیز کنید .

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

aminbin
سه شنبه 23 آبان 1396, 11:53 صبح
دوستان آیا با transaction مشکل رو حل نمیشه؟ یعنی آیا این قابلیت رو داره که اگه چند تا کاربر همزمان درخواست ثبت دادن ، عمل ثبت رو یکی یکی انجام بده؟

ali_md110
سه شنبه 23 آبان 1396, 13:14 عصر
از کلید ترکیبی برای کلید اصلی استفاداه کنید
مثلا IDو کد کاربری هر دو بشن یک کلید

aminbin
چهارشنبه 24 آبان 1396, 10:10 صبح
من متوجه شدم که راه حل مشکلم این هست که به نوعی باید جدول مورد نظرم رو قفل کنم . تا کاربرای دیگه نتونن دیگه ازش بخونن یا بنویسن. خواهشا در مورد پیاده سازی Lock جدول در ef بنده رو راهنمایی کنید. من خیلی در موردش جستجو کردم و بیشتر گیج شدم. لطفا من رو راهنمایی بفرمایید.

ali_md110
چهارشنبه 24 آبان 1396, 11:04 صبح
یک فیلد بنام Rowversion با نوع timestamp اضافه کنید به جدولتون
دیگه کاری نیاز نیست بکنید
حتی کد هم نمیخاد بنویسید
Sql server بصورت اتوماتیک یک مقدار Uniq به این فیلد اضافه میکنه
و اگر کاربری بخاد رکورد مورد نظر رو ویرایش بکنه اجازه نمیده و خطا و استثناء پرتاب میکنه

aminbin
چهارشنبه 24 آبان 1396, 11:15 صبح
یک فیلد بنام Rowversion با نوع timestamp اضافه کنید به جدولتون
دیگه کاری نیاز نیست بکنید
حتی کد هم نمیخاد بنویسید
Sql server بصورت اتوماتیک یک مقدار Uniq به این فیلد اضافه میکنه
و اگر کاربری بخاد رکورد مورد نظر رو ویرایش بکنه اجازه نمیده و خطا و استثناء پرتاب میکنه

خیلی ممنون از راهنماییتون. فقط یک سوالی . این روش به طور کلی جدول رو قفل میکنه؟ هم برای select هم update , insert ؟

nadia92
چهارشنبه 24 آبان 1396, 12:37 عصر
دوست عزیز سلام.
شما نگرا نباشید همین روشتون رو پیش برید.
سیستم کار sql خودش اینطوریه که تا وقتی که یک سیشن کارش به اتمام نرسیده باشه اجازه درج یا آپدیت یا سلکت به سیشن دیگه ای نمیده.
من و شما اگر همزمان بخواهیم درج کنیم مطمئنننننننننننن باشید یکی از ما دوتا زودتر به سرور میرسیم, حتی اگر باهم هم برسیم sql یکی از مارو انتخاب میکنه. بعد خودش رو لاک میکنه تا کار یکیمون تموم که شد کار اون یکی رو شروع کنه.
پیشنهاد میکنم بدون نگرانی کارتون رو پیش ببرید

ali_md110
چهارشنبه 24 آبان 1396, 12:55 عصر
خیلی ممنون از راهنماییتون. فقط یک سوالی . این روش به طور کلی جدول رو قفل میکنه؟ هم برای select هم update , insert ؟
وقتی دو یا چند کاربر همزمان روی یک (رکورد ) ویرایش انجام میدن
وگرنه در حالت select که تاثیری نداره

a.golzar66
چهارشنبه 24 آبان 1396, 12:59 عصر
سلام
اتفاقا من هم همین مشکل رو دارم و اگر دو تا کاربر یا بیشتر همزمان با هم مثلا روی دکمه submit کلیک کنند، به انها شماره فاکتور تکراری میده (چون میاد یکی به اخرین شماره فاکتور زیاد میکنه).
یکی از دوستان گفت باید با async و await کار کنم ولی باز هم درست نشد

a.golzar66
چهارشنبه 24 آبان 1396, 13:23 عصر
دوست عزیز برای حالت select چه راهی وجود داره؟؟

Moien Tajik
چهارشنبه 24 آبان 1396, 13:42 عصر
درباره ی optimistic concurrency جستجو کنید.

یک مثال برای استفاده در Entity Framework :
https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application (https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application)

a.golzar66
چهارشنبه 24 آبان 1396, 16:03 عصر
ببینید من میخوام اگر دو نفر همزمان یک متد را اجرا کردند به یک روشی ابتدا به یکی از درخواست ها پاسخ بده بعد به دیگری.
حتی در جدول مربوطه به گفته دوستمون فیلد
timestamp اضاف کردم.ولی وقتی همزمان روی دکمه ثبت کلیک میشه باز هم شماره فاکتور یکسان میده:متفکر:

ali_md110
چهارشنبه 24 آبان 1396, 18:36 عصر
اگر میخاید یک کلید یکتا تولید کنید یا باید ازGUID استفاده کنید
یا همون کلید ترکیبی که بالا اشاره کردم

a.golzar66
پنج شنبه 25 آبان 1396, 08:05 صبح
من منظورم از شماره فاکتور کلید نیست بلکه یک فیلد از جدول هست که هربار با کلیک کاربر یک متد صدا زده میشه ویه اخرین مقدار موجود این فیلد در جدول یکی اضافه میکنه که اگر همزمان دو نفر کلیک کنند ، اخرین مقدار این فیلد تکراری برگردانده میشه و در نتیجه شماره فاکتور جدید هم تکراری میاد برای هر دو فاکتور

aminbin
پنج شنبه 25 آبان 1396, 08:17 صبح
من منظورم از شماره فاکتور کلید نیست بلکه یک فیلد از جدول هست که هربار با کلیک کاربر یک متد صدا زده میشه ویه اخرین مقدار موجود این فیلد در جدول یکی اضافه میکنه که اگر همزمان دو نفر کلیک کنند ، اخرین مقدار این فیلد تکراری برگردانده میشه و در نتیجه شماره فاکتور جدید هم تکراری میاد برای هر دو فاکتور

دقیقا من هم شرایط برنامم همین طوریه. امکان استفاده از Guid هم ندارم. چون اون کد برام مهم هست.

a.golzar66
پنج شنبه 25 آبان 1396, 08:58 صبح
این وسط من یه چیز رو متوجه نشدم.اگر ما در یک اکشن از async و await استفاده کنیم ان موقع اگر همزمان کاربرهای دیگری هم به ان اکشن request بفرستند ،همزمان به درخواست همه انها پاسخ داده میشه و کاربری معطل نمیشه ولی اگر بدون async و به صورت عادی یک اکشن توسط چند کاربر اجرا بشه اول به درخواست یکی پاسخ داده میشه بعد که کارش تموم شد به درخواست بعدی یعنی به صورت نوبتی اجرا میشن.پس چرا من و دوستم هردو این مشکل مثلا شماره فاکتور تکراری را داریم؟مگر نه این هست که چون از async استفاده نکردیم پس اکشن هربار به یک درخواست پاسخ میدهد و نباید شماره فاکتور تکراری بدهد:افسرده: