PDA

View Full Version : هزينه استفاده از تراكنش و قفل بر روي Server شبكه ؟



Developer Programmer
سه شنبه 26 خرداد 1388, 17:41 عصر
سلام
توي اين شركتي كه من كار ميكنم يه روشي استفاده ميكنن كه جالبه ؛ تقريبا توي تمام فرمهاشون يكبار تمام آبجكتها رو Fill ميكنن؛ يعني Select ميكنن و ميريزن تو كنترلها؛ بعد هر وقت كه روي سطري از Grid كليك كردي؛ مقادير رو مي ريزن توي TextBox و ويرايش و اضافه و ساير كارها رو اونطوري ادامه ميدن.
حالا مثلا زماني كه ميخوان ويرايش كنن، يكبار Select ميكنن كه كليد اصلي تكراري نباشه، بعد چك ميكنه كه قبلا از اين سطر جايي نباشه (اطلاعات غيرتكراري) بعد مياد و اونرو در جدول درج ميكنه.
تصور من اينه كه در فاصله زماني كه تو داري تكراري نبودن كليد اصلي رو چك ميكني يا تكراري نبودن فيدهاي سطري رو چك ميكني؛ كاربر ديگه ميتونه اون مقادير رو زودتر از تو چك كنه و اجازه Insert و Update بگيره و بعدش هم تو Insert , Update كني... و اينطوري داده هاي تكراري ايجاد بشن؛ علاوه بر اينكه ممكنه به خاطر تكراري بودن كليد اصلي خطا پيش بياد و عمليات شكست بخوره
پيشنهاد من با كلي بحث اين بود كه از TabLock در هنگام چك كردن تكراري بودن مقادير و از rowLock (در غالب تراكنش) قبل از Update كردن سطر، استفاده بشه... اما شركت اصرار داره كه هزينه تراكتش ها واسه Server ميتونه سنگين باشه و ضمن اينكه الان مدتيه كه با يه همچين برنامه اي شركت داره كار ميكنه و مشكلي هم پيش نيومده پس لازم نيست نگرون مشكل همزماني باشيم.

ميخواستم بدونم نظرتون در مورد استفاده كردن يا نكردن از قفل و تراكنش چيه و آيا از قفل هاي مناسبي استفاده ميكنم يا نه

اوبالیت به بو
پنج شنبه 28 خرداد 1388, 15:48 عصر
حالا مثلا زماني كه ميخوان ويرايش كنن، يكبار Select ميكنن كه كليد اصلي تكراري نباشه، بعد چك ميكنه كه قبلا از اين سطر جايي نباشه (اطلاعات غيرتكراري) بعد مياد و اونرو در جدول درج ميكنه.

يعني براي ويرايش اين كار رو مي كنن:
1- يه select براي عدم تكراري بودن.
2- قبل از Insert يه چك مي كنه كه در جايي وجود نداشته باشه.
3- Insert
آيا پس از درج، ركورد ويرايش شده Hide ميشه؟

تصور من اينه كه در فاصله زماني كه تو داري تكراري نبودن كليد اصلي رو چك ميكني يا تكراري نبودن فيدهاي سطري رو چك ميكني؛ كاربر ديگه ميتونه اون مقادير رو زودتر از تو چك كنه و اجازه Insert و Update بگيره و بعدش هم تو Insert , Update كني... و اينطوري داده هاي تكراري ايجاد بشن؛ علاوه بر اينكه ممكنه به خاطر تكراري بودن كليد اصلي خطا پيش بياد و عمليات شكست بخوره
فكر كنم فكر اينجا رو كردن. مثلاً شما يك ركورد رو در دست ميگيري اون ركورد Lock ميشه و كاربر ديگه نمي تونه استفاده كنه. يكبار خودتون تست كنيد ببينيد ميشه دو كاربر با يك ركورد كار كنند؟

Developer Programmer
جمعه 29 خرداد 1388, 18:28 عصر
آيا پس از درج، ركورد ويرايش شده Hide ميشه؟
خیر یوزر باید زحمت پاک کردن رکورد قبلی رو بکشه.

فكر كنم فكر اينجا رو كردن.
نه نکردن


مثلاً شما يك ركورد رو در دست ميگيري اون ركورد Lock ميشه و كاربر ديگه نمي تونه استفاده كنه. يكبار خودتون تست كنيد ببينيد ميشه دو كاربر با يك ركورد كار كنند؟

وقتی یه Select زدی و داری Count میکنی و تازه میخوای که Insert یا Update کنی؛ مگه میشی رکورد lock شده باشه؟
به بالا دقت کرده بودی گفتم گرید رو Fill میکنن نه بایند ؟

HDDSoft2001
جمعه 27 شهریور 1388, 03:47 صبح
با سلام

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

نظر من اينه كه روي جدول قفل بذاريم در طول اين مدت و سپس ازادش كنيم. فكر نكنم زمانش زياد طول بگشه. ولي من تا حالا با قفل ها كار نكردم كسي بلد بود به ما هم بگه.

راستي نتيچه اين بحث اخرش چي شد دوستان اگه درجريان هستيد به ما هم بگيد. به قول معروف فوري فوتيه.


با تشكر

Developer Programmer
جمعه 27 شهریور 1388, 10:51 صبح
begin tran
select count(*) with (tablockx,hollock) from table1
...
if @error=1 then
commit
else
rollback

HDDSoft2001
جمعه 27 شهریور 1388, 23:13 عصر
با سلام


دوست عزيز خيلي ممنونم ولي اگه ميشه يه توضيح جزئي از كاركرد و سناريوي اون بديد.


با تشكر

k_m
شنبه 28 شهریور 1388, 02:40 صبح
با سلام
به نظر من استفاده از تراکنش هابرای جلوگری از همزمانی تغییر هزینه بر است. و فکر نمی کنم استفاده از تراکنش ها برای این مساله معقول باشد.
برای آپدیت کردن، شاید چک کردن با مقادیر قبلی( مقادیر خوانده شده قبلی)در whereدستور sql کار ساز باشد .
اینجوری اگر مقادیر در فاصله خواندن و تغییر اطلاعات توسط شما،توسط شخص دیگری تغییر یافته باشد، قابل تشخیص است.

Developer Programmer
شنبه 28 شهریور 1388, 12:09 عصر
دوست عزيز خيلي ممنونم ولي اگه ميشه يه توضيح جزئي از كاركرد و سناريوي اون بديد.
من یه نمونه کوچیک که بتونه راه رو بهت نشون بده ارائه کردم. لطفا بقیه جزئیات رو از MSDN بخون


فکر نمی کنم استفاده از تراکنش ها برای این مساله معقول باشد.
فکر نمیکنی چون به سناریویی که دوستمون ذکر کرد دقت نکردی
دوستمون لازم داره چندین عمل رو همراه با قفل کردن انجام بده و منطقا اگه یکیشون انجام نشد نباید بقیه انجام بشن.
من از تراکنش به این دلیل استفاده کردم . از HoldLock هم به این دلیل که تا تراکنش تموم نشده قفل رو آزاد نکنه

HDDSoft2001
شنبه 28 شهریور 1388, 12:31 عصر
با سلام

ممنونم ولي دوستوري كه گفتي از نظر املايي خطا داره و اجرا نميشه.

نظرتون در مورد كد زير چيست؟



declare @_ID int
select @ID = Max(ID) from tblSanad
if (@ID is null )
set @ID = 0 -- for first insert in table, beacause first term table is empty

insert into tblSanad (ID)
values (@ID+1)

While (@@error <> 0) begin
select @ID = Max(ID) from tblSanad

insert into tblSanad (ID)
values (@ID+1)
end