PDA

View Full Version : مشکل استفاده از Transaction ها در dbisam



MNosouhi
چهارشنبه 09 اسفند 1385, 12:52 عصر
امروز به یه باگ تابلو توی dbisam برخورد کردم ، به این صورت که اگه از DBISAMUpdateSQL برای Update یه جدول در داخل Transaction استفاده کنید برنامتون قفل می کنه ، به کد زیر توجه کنید :

procedure TForm1.Button7Click(Sender: TObject);
var s:TStrings;
begin
try
s:=TStringList.Create;
s.Add('ser');
ADOConnection.StartTransaction(s);
Try
TableSer.Cancel;
DBISAMUpdateSQL1.SQL[ukModify].Clear;
DBISAMUpdateSQL1.SQL[ukModify].Add('Update "'+ExtractFileDir(Application.ExeName)+'\d\ser'+'"');
DBISAMUpdateSQL1.SQL[ukModify].Add('Set SCCode='+Trim(Edit1.Text));
DBISAMUpdateSQL1.SQL[ukModify].Add('where SCode='+Trim(Edit2.Text));
DBISAMUpdateSQL1.Apply(ukModify);
TableSer.Refresh;
ADOConnection.Commit;
except
ADOConnection.Rollback;
ShowMessage('Errore');
end;
finally
s.Free;
end;
end;
همونطوری که میبینید فقط یک دستور Update ساده در داخل یه transaction نوشته شده ، اما اگه تستش کنید میبینید که برنامتون قفل می کنه ، وقتی داخل سورس dbisam رو برای پیدا کردن علت قفل کردن برنامه بررسی کردم متوجه شدم که خود دستور update از transaction ها استفاده می کنه ، اما چون دو تا Transaction نمی تونن همزمان بر روی یک جدول کار کنن ، بنابر این transaction ناشی از دستور Update منتظر میشه تا Transaaction ی که در کد بالا خودمون ایجاد کردیم تموم بشه ، تموم شدن Transaction ی هم که خودمون نوشتیم مشزوط بر اینه که دستور Update انجام بشه و اینجا یه حلقه بوجود میاد که هر کدوم منظر تموم شدن کار دیگری هستش (بن بست ) .
حالا من نمیدونم که چطوری باید این مشکل رو برطرف کنم ، چونکه واقعا بهش احتیاج دارم ، اگه دوستان قبلا با این مشکل برخورد کردن و جوابی براش دارن کمک کنن.
ضمنا از نسخه 4.19 استفاده میکنم.

ghabil
چهارشنبه 09 اسفند 1385, 22:53 عصر
[QUOTE=MNosouhi;313583]
[ ADOConnection.StartTransaction(s);
Try
TableSer.Cancel;
DBISAMUpdateSQL1.SQL[ukModify].Clear;
DBISAMUpdateSQL1.SQL[ukModify].Add('Update "'+ExtractFileDir(Application.ExeName)+'\d\ser'+'"');
DBISAMUpdateSQL1.SQL[ukModify].Add('Set SCCode='+Trim(Edit1.Text));
DBISAMUpdateSQL1.SQL[ukModify].Add('where SCode='+Trim(Edit2.Text));
DBISAMUpdateSQL1.Apply(ukModify);
TableSer.Refresh;
ADOConnection.Commit;
except
ADOConnection.Rollback;
ShowMessage('Errore');
end;
end;[/CODE]

سلام چطوری؟

آقا من تا حالا اصلا DBISAM کار نکردم و راستش ایده کاملی هم از اینکه داری اینجا چی کار میکنی بدست نیاوردم اما : اولا بعیده که این باگ باشه ، دوما این جریان کنسل و Refresh که میکنی چیه ؟ اونم وسط Transaction روی همون Table ؟ چرا اینارو نزاشتی بیرون ترانزاکشن (چون فکر میکنم اینا برای UI هستند. ) من دقیقا نمیدونم DBISAM چطوری Lock میکنه اما حداقل با BeginTrans تو یک ReadOnly Lock روی جدول میگیره ، حالا تو اونوسط چی رو کنسل میکنی و چرا دوباره از Table اطلاعات میخونی یکمی عجیبه (البته اگر درست فهمیده باشم و این همون جدول باشه)، خلاصه که شده تست کنی Cancel و Refresh رو بزاری بیرون ترنس؟
راستی تجربی هم اینو پیشنهاد میکنم که توی Except بجای ShowMessage حتما Raise Exception کن ، مگر اینکه دلیل خاصی بداشته باشی...

MNosouhi
چهارشنبه 09 اسفند 1385, 23:55 عصر
اولا بعیده که این باگ باشه
راستش خیلی خوشحال میشدم اگر این اشتباه من بود ، راهنمای اون هم چیزی در موردش نگفته ، به هر حال دوستان میتونن تست کنن .

دوما این جریان کنسل و Refresh که میکنی چیه ؟
اگر جدول در حال ویرایش باشه ( یا شاید بهتر باشه بگم در حالت browse نباشه ) و من بخام از DBISAMUpdateSQL استفاده کنم ، هنگام Apply کردن با خطا مواجه میشم . برای همین قبل از استفاده از Apply جدول رو cancel می کنم تا اگر احیانا در حالت browse نباشه به حالت browse برگرده. بعد از انجام عملیات توسط DBISAMUpdateSQL هم جدول رو رفرش میکنم تا تغییرات انجام شده در grid قابل مشاهده باشه.

چرا اینارو نزاشتی بیرون ترانزاکشن
از تذکرتون ممنون ، اصلا حواسم نبود.

راستی تجربی هم اینو پیشنهاد میکنم که توی Except بجای ShowMessage حتما Raise Exception کن ، مگر اینکه دلیل خاصی بداشته باشی...
آره ، در کد اصلیم همین کاری که شما فرموده اید رو کرده ام.
از اینکه جواب دادید ممنون .