Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

FK в IB6.0 - Firebird. Невозможно массовое удаление-добавление [D5, IB6.x]


Страницы:   1 2

kaif ©   (2002-06-28 23:17:00) 

Имеется таблица Table1 (ID, ID2, NAME).
Имеется таблица Table2 (ID, NAME).
Имеется декларативная ссылочная целостность
alter table1 add constraint fk_table1_to_table2
foreign key(ID2) references Table2(ID).
1.Вставляем 10000 записей в Table1.
2.Выходим из приложения.
3.Соединяемся еще раз и удаляем 10000 записей из Table1.
4.Вставляем 10000 новых записей в Table1.
5.Выходим из приложения.
6.Соединяемся еще раз. Делаем любой SELECT запрос к таблице Table1.
7.Пытаемся выйти из приложения. Сервер виснет. Процессор не занят. Никакие действия с сервером (другое соединение) невозможны. Искусственное прекращение работы сервера (снять задачу) приводит к разрушению базы данных (orphan pages).
---------------------
Без foreign key такого не происходит.
Я провел сотни экспериментов. Менял сервер (IB6, Firbird). Менял параметры транзакции (snapshot, consistency, read committed). Все без толку. Описанные выше 7 шагов вешают сервер. Не завершает работу функция клиента
isc_detach_database.
Любопытно, что если подождать минут 20-30, приложение все же завершается. Однако все это время оно ничем не занято, к диску тоже обращений не происходит. Я слежу по Task Monitor NT4. То же положение и в Windows"98. Спокойно можно запускать другие приложения и работать.
Чем занят сервер?
Кто знает?
Ссылочная целостность через FK и так уже мне крови попортила достаточно. Но это уже полный беспредел...


kaif   (2002-07-01 13:27:00) [21]

>2Alexandr
Ну как, доставилось мыло или еще нет?


kaif   (2002-07-01 13:25:00) [22]

Я тут копаюсь в литературе и шевелю мозгой. Я так думаю: если в триггере возможен SQL-запрос (а он возможен!), следовательно, триггер исполняется в контексте транзакции. Логически иначе быть не может. Хотя я уже давно стал эмпириком. Можно, впрочем проверить...
Что же теперь делать?...
Я не знаю. Последняя надежда, что у меня с железом что-то не то. Хотя вряд ли... Причем тут железо?
А делать проверку ссылочной целостности в контексте транзакции - все равно, что делать ее вообще со стороны клиента. Или даже хуже... С клиента я могу хотя бы стартовать свежую транзакцию. А до триггера данные могут сильно устареть...


kaif   (2002-07-01 13:10:00) [23]

Вроде отправил. Если пример нужно доработать (сделать диалог подключения к базе) - скажите. Это тот код, с помощью которого я сам разбирался. Если убрать FK (drop constraint...), то можно сколько угодно раз нажимать кнопку Insert-Update. Если же FK присуствует, то после нескольких таких сеансов возникнут проблемы с отсоединением от базы после SELECT. Любопытно, что если сделать Validity Check перед этим SELECT, то сервер скажет, что база в полном порядке.


Alexandr   (2002-07-01 13:04:00) [24]

чего-то письма до сих пор нема...


Alexandr   (2002-07-01 12:44:00) [25]

2kaif:
1) Жду мыло...
2) триггеры выполняются в контексте транзакции. Это естественно как коже, что солце встает на востоке, а заходит на западе...
И все другие мнения неправильные.
3)нИЧЕго сложного в общении с разработчиками Firebird, а уж тем более с разработчиками Yaffil нет. Нужна просто достаточная квалификация, чтоб они не подумали, что ты глупый ламер.



kaif   (2002-07-01 12:36:00) [26]

>2 Alexandr © (01.07.02 06:48)
То, что Вы говорите очень важно. Неужели триггеры выполняются в контексте транзакции? Мне тут на форуме попадалась иная точка зрения и, честно говоря, я принял это за чистую монету. Я еще взгляну в документации по IB, но, насколько я помню, там об этом подробно не пишется...
Ваше предложение отправить кому следует меня сильно заинтересовало, так как я сам никак не возьму в толк, как связаться с ребятами из проекта Firebird... Если не возражаете, я прямо сейчас кину Вам на ящик тестовый пример.
Кстати, я попробовал Yaffils. В нем ошибка та же, но проявляется иначе. Приложение немного виснет при дисконнекте (секунд 20), а потом вылетает с сообщением Windows "Программа выполнила недопустимую операцию...". Сам Yaffils мне как-то не понравился - у меня резко (раза в 3) стало медленнее все работать. Не знаю... Просто у меня очень сложный проект и экспериментировать времени нет. Я уже остановился на Firebird. В целом он меня очень устраивает...


Alexandr   (2002-07-01 06:48:00) [27]

2kaif:
1) Можно мне тестовый примерчик с этим глюком? Посмотрю и если глюка действительно в сервере, то отправлю кому следует...
2) ПОЛНОЦЕННУЮ Ссылочную целостность на триггерах создать НЕВОЗМОЖНО. Поскольку триггера выполняются в контексте транзакции, в отличие от ForeignKey.


jedi   (2002-07-01 00:11:00) [28]

Transaction.StartTransaction;
SQL.Text :=
"INSERT INTO TABLE1(ID,ID2,NAME)"#13+
"SELECT ID, cast(1 as integer), NAME FROM PROC1(10000)";
ExecSQL;
Transaction.Commit;

u vas tut proishodit insert na 10000 zapisei, poprobuite posle inserta cajdoi stroki sdelat" commit (nipsat" sql po drugomu);

Hotea na samom dele naverno takoi problemi katoruiu vi naverhu opisali ne doljno voznicat".
Edinstvennoe 4to eshe mogu poprobovat" posovetovat" tak napisat" pro bug grupe razrabot4ikov Firebird i esli ato destvitel"no bug to vozmojno oni ato delo ispraveat :).


kaif   (2002-06-30 23:53:00) [29]

>2 jedi © (30.06.02 20:03)
Что Вы! Вы меня не обидели.
Хотите я приведу кусок кода, а Вы мне скажете, много ли операций я делаю до commit?

procedure TForm1.Button1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
with Query do
try
if Active then Close;
with Transaction do
if Active then Commit;
if not db.Connected then db.Connected := True;

Transaction.StartTransaction;
SQL.Text := "DELETE FROM TABLE1";
ExecSQL;
Transaction.Commit;

Transaction.StartTransaction;
SQL.Text := "SELECT COUNT(*) FROM TABLE1";
Open;
Transaction.Commit;

Transaction.StartTransaction;
SQL.Text :=
"INSERT INTO TABLE1(ID,ID2,NAME)"#13+
"SELECT ID, cast(1 as integer), NAME FROM PROC1(10000)";
ExecSQL;
Transaction.Commit;

finally
Screen.Cursor := crDefault;
end;
end;

Этого достаточно. Можете сами попробовать. Я не вижу ничего криминального в этом коде. Он прекрасно работает, если нет foreign key. Как видите, я подтверждаю каждую команду с помощью commit. Я считаю, что это в высшей степени тривиальный код.
Я работаю с IB уже лет 5. И очень люблю этот сервер. Просто пока мне не приходилось делать массовых удалений и я не сталкивался с данной проблемой. Жаль, что с foreign key столько проблем...


jedi   (2002-06-30 20:03:00) [30]

1. Neponyatno kak i za4em odno pole mojet silatsya na primary
key iz dvuh ili bolee tablits.
2. Ne sovsem verno kak vi ih sozdaiote vobshe ta kak sozdanie
vneshnevo kliu4a cac i liubogo drugo obiecta podruzumevaet
odin connect c baze ;-) (shitka) a vabshe ato destvitel"no
problema
3. Ne provereal

Ya dumaiu esli vi poprobuite delat" ta kak ya napisal vishe to problem ne budet, to est":

1. startuete tranzactsiu
2. delaete nekotoroe koli4estvo DML operatsii (nebol"shoe)
3. Commit
4. Opeat" to je samoe ;-)

V liuboi baze dannih ne recomenduiutsea delat" ogromnoe mnojestvo DML operatsii v odnoi tranzactsii naprimer v Oarcle ato zvyazanno s zaponeniem rollback segmentov 4to o4en" silno scazivatsea na proizvodidel"nosti.

P.S. S Interbase ya po4ti ne rabotal, prosto hotel predlojit" ideiu kak izbejat" vashusituatsiu, sorry esli ya vas obidel ;-)


kaif   (2002-06-30 19:25:00) [31]

>2 jedi © (30.06.02 18:25)
А почему Вы считаете, что такая ситуация невозможна?
Приведу целый ряд "невозможных" ошибок InterBase6.0:
1. При попытке создать Foreign Key на поле, являющееся в свою очередь полем, имеющим Foreign Key на другую таблицу происходит сбой в IB6.0. В Firebird Эта ошибка исправлена.
2. Если имеется еще хоть одно подключение к базе данных, создание любого Foreign Key невозможно с идиотским сообщением "Table is in use", хотя с ни с одной таблицей никто не работает (просто connect). Будем считать это идеологическим ограничением, ладно...
3. Но если имеется еще подключение к другойбазе, в которой есть одноименная (!!!)таблица той, на которую я устанавливаю ссылку Foreign Key в этойбазе, возникает то же самое сообщение "Table is in use", хотя это Table в другой базе in use, а не в этой. Эта ошибка присуствует и в Firebird тоже.
4. И наконец, невозможность массового удаления - добавления, о которой я пишу.
Я полностью отказываюсь с этих пор использовать FK механизм IB. Все пропишу в триггерах. Я потерял суммарно минимум 3 недели работы на всех этих интересных особенностях... Не говоря о том, что пришлось переходить на Firebird, что меня не вполне устраивало...


jedi   (2002-06-30 18:25:00) [32]

Mojet u tebea problemi s jelezom ? Potomu 4to takya situatsia v printsipe nevozmojna. Poprobuiu na drugom compiutore, ispol"zui lu4she SQL i ne delay o4eni bolishie tranzactsii hotea bi posle kajdie 100 DML operatsii delay commit.


kaif   (2002-06-30 13:40:00) [33]

Нет, не мусор. Я делаю запросы типа
SELECT COUNT(*) FROM TABLE1 в отдельной транзакции после commit основной. Потом уборка мусора 10тыс. строк не может занимать 20-30 мин. В худшем случае - 2 сек. И наконец, сервер не просто тормозит. Он клинит. Никакое обращение к нему из других соединений попросту не работает (виснет любое обращение). И процессор ничем не занят.
К тому же до попытки отсоединиться второй раз база работает великолепно. Никаких тормозов или еще чего подобного не замечается...
Потом, если это уборка мусора, то при чем тогда foreign key?
Повторяю, без foreign key эту ситуацию не удается воспроизвести даже на вставке 100тыс строк. А с foreign key при размере файла базы в 10М эта ситуация происходит после удаления-вставки даже 1 тыс. строк.


Wizard_Ex   (2002-06-30 09:53:00) [34]

Она у тебя случаем не мусор подбирает при последнем селекте
Ж-0


kaif   (2002-06-29 15:17:00) [35]

Неужели никто с этим не сталкивался?
Не может такого быть...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо