PDA

View Full Version : کنترل Unique بودن مقدار فیلد در شبکه



daivid_az
شنبه 03 شهریور 1386, 12:17 عصر
با سلام محضر کلیه دوستان
فرض کنیم در محیط شبکه دو نفر کاربر بخواهند رکوردی را به یک جدول که دارای یک فیلد کلید نیز می باشد اضافه کنند ، و قرار است پس از تایید کاربر این رکورد به صورت فیزیکی به جدول Add شود. اما سئوال ؟
چه روشی به نظر شما برای کنترل این وضعیت به لحاظ Performance است؟
اینکه به محض ایجاد رکورد توسط کاربر بصورت فیزیکی نیز رکورد در جدول اضافه شود و در صورت عدم تایید آن را حذف کنیم یا از یک جدول کمکی با یک فیلد که تنها مقدار فیلد کلید را نگه داشته و در صورت عدم تایید کاربر تنها این مقدار از این حذف شود .
توجه فرمایید که در محیط شبکه ممکن است چند کاربر هم زمان شروع به اضافه کردن رکورد نمایند و قاعدتا هر کدام می بایستی مقدار جدیدی بگیرندو این وضعیت ممکن است در جداول رابطه ای مانند فاکتور فروش باشد.
با تشکر

پویا
شنبه 03 شهریور 1386, 13:47 عصر
اگر از فیلد Identity برای اینکار استفاده کرده باشید روی شبکه هم مشکلی ندارید.
اگر نوع فیلد شما چیزه دیگری است می توانید از تریگر برای مقدار دهی به آن فیلد استفاده کنید.

مشکلات را به عهده SQL بگذارید ؛)

daivid_az
شنبه 03 شهریور 1386, 14:54 عصر
دوست عزیزم
ضمن عرض سلام و تشکر، شما مطلب فوق را با این نکته در نظر بگبرید که ارتباط با جداول از طریق شی DataAdapter بوده و قرار است پس ازاجراء متد Update این شی، جدول به روز شده و فیلد مورد نظر در جدول مقدار بگیرد حال اگر دو تا کاربر هم زمان به جدول وصل شده باشند مثلا مقدار 5 را دریافت می کنند (یعنی آخرین مقدار 4 بوده) حال هر کدام زودتر متد Update را اجرا کند مقدار 5 به او تخصیص و برای نفر بعد مقدار شش باید تخصیص داده شود پس مهم اخذ مقدار فیلد در این فاصله زمانی می باشد. نه در لحظه Update یا commit شدن

AminSobati
یک شنبه 04 شهریور 1386, 13:07 عصر
دوست عزیزم،
زمانی که اطلاعات تکراری بخواد در PK وارد بشه، خود SQL Server جلوی این تکرار رو خواهد گرفت. یعنی نیازی به حذف ندارید. همونطور که دوستان اشاره کردند، استفاده از Identity حتی در محیط چند-کاربره هم مشکلی نخواهد داشت.

رضا عربلو
یک شنبه 04 شهریور 1386, 23:14 عصر
یک مشکلی که فیلد Idenity دارد این است که هنگامی که به هر دلیلی عملیات اینزرت به شکست انجامید در عمل اینزرت بعدی از شماره بعدی استفاده می شود.
و در موارد خاصی ممکن است که بخواهیم اعداد در هر صورتی پشت سر هم باشند.

AminSobati
یک شنبه 04 شهریور 1386, 23:44 عصر
در این حالت باید ID رو خودتون تولید کنین. برای جلوگیری از تولید ID تکراری، میتونین آخرین ID رو در جدولی ذخیره کنین و یک SP داشته باشید که براتون ID جدید تهیه میکنه. در این SP، میبایست مقدار جدول رو با xlock بخونین و Update کنین تا در آن واحد، تنها یک کاربر بتونه مقداری رو از جدول بخونه. با توجه به اینکه چنین جدولی تنها یک فیلد و یک رکورد داره، مشکل همزمانی در فراخوانی SP نخواهید داشت چون کار در چند هزارم ثانیه انجام میشه

رضا عربلو
سه شنبه 06 شهریور 1386, 00:13 صبح
من معمولاً از یک sp که ID آخرین فیلد table را می خواند و یکی به آن اضافه می کند در یک ترنس اکشن استفاده می کنم.
آیا این روش ممکن است به مشکل بخورد؟
فکر می کنید کدام بهتر باشد؟

پویا
سه شنبه 06 شهریور 1386, 13:56 عصر
من برای این کار درست قبل از دستور اینزرت آخرین مقدار رو پیدا می کنم و یکی بهش اضافه می کنم همون طور که آقای ثباتی گفتند چون این عمل در چند هزار ثانیه انجام میشه احتمال بروز مشکل تقریبا صفر است

البته برای این کار من از یه جدول دیگه استفاده نکردم و از خود جدول مورد نظر اخرین مقدار رو محاسبه می کنم
تا حالا هم هیچ مشکلی نداشتم

AminSobati
چهارشنبه 07 شهریور 1386, 09:53 صبح
خواندن آخرین رکورد از خود جدول مشکلش اینه که ممکنه دو کاربر همزمان این عمل رو انجام بدن، و هر چقدر هم این کار سریع اتفاق بیافته، احتمالش هست که دو کاربر، مقدار یکسان بدست بیارند. مگر اینکه از Hintهای مثلا xlock و holdlock استفاده کنین تا کسی همزمان نتونه بخونه. این هم مشکلش اینه که جدول رو lock میکنه. اصولی ترین کار این هست که این عملیات در جدول دیگه ای انجام بشه