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

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

Кто понимает смысл ошибки "Таблица мутирует" ? [Оракл]


Страницы:   1 2 3 4

ANB ©   (2006-09-04 16:06:00) 

В общем то смысл самой ошибки понятен. И как ее избегать я знаю. А вот смыл ее генерации ? Неужели нельзя ораклу было без нее обойтись ? Почему я не могу селекать в триггере изменяющуюся таблицу ?


ANB   (2006-09-05 19:40:00) [21]


> > Автономная транзакция же исправляет ситуацию.
> Это заблуждение.

Функция перестала падать.

Ща доработает - на триггере потренируюсь. Но эта прагма автоматически включает чтение старых данных.


Desdechado   (2006-09-05 19:31:00) [22]

> Автономная транзакция же исправляет ситуацию.
Это заблуждение.


ANB   (2006-09-05 19:23:00) [23]


> Выгоднее делать новые фичи, чем Ларри успешно занимается.

Ну так прагму бы добавили для тех, кому неохота возится с этой ошибкой. Автономная транзакция же исправляет ситуацию.


> Ты скажи, ты завел этот топик, чтобы высказать свое возмущение
> или послушать объяснения?

Высказать возмущения, послушав объяснения (может я чего не догонял или в FB таже картина). Я то считал, что кроме оракла сия ошибка больше нигде не встречается.


Desdechado   (2006-09-05 19:15:00) [24]

ANB ©
Ты скажи, ты завел этот топик, чтобы высказать свое возмущение или послушать объяснения?
Возмущения понятны, но, имхо, от них все равно ничего не изменится. Прими механизм как данность. Просто теперь им не выгодно менять логику поведения сервера, слишком много у всех заточек на старый механизм, а обратной совместимости никто не отменял.
Выгоднее делать новые фичи, чем Ларри успешно занимается.


ANB   (2006-09-05 18:56:00) [25]

Кстати, по поводу неоднозначности.

Вот такой оператор :

update Table2 set Status = rownum

будет выполнен без проблем, хотя его результат тоже неоднозначен и зависит от настроения сервера.

Однако этот случай задокументирован, ошибка не генерится.


ANB   (2006-09-05 17:44:00) [26]


> AFAIR, order by в инсерте недопустим.

хм. напиши групповой инсерт без селекта.


> построив базу "правильно".

Имхо - правильно, это использовать триггера. А от этого сплошь и рядом приходится отказываться или городить кучу объектов для обхода


> Если FB такое позволяет, поэкспериментируй на нем. Возможность
> получить разные результаты выполнения - это уже баги. Оракл
> эту возможность пресёк.

Мне подход FB больше нравится. А такое пресекание "отберем у всех в Москве спички, чтобы ничего не спалили в деревне Гадюкино" режет фукциональность.


> А транзакция тут при чем? Речь идет о групповой замене за
> один присест, в одном операторе

ПОСЛЕ оператора до коммита в таблице лежат новые данные, в RBS - старые.
А вот где что лежит во время выполнения оператора - х.з. (знаний маловато).


evvcom   (2006-09-05 17:29:00) [27]

> [49] ANB ©   (05.09.06 17:14)
> логического противоречия никакого нет.

Есть. Вникни в пример [39]. Если FB такое позволяет, поэкспериментируй на нем. Возможность получить разные результаты выполнения - это уже баги. Оракл эту возможность пресёк.

> 1) далеко не всегда эта последовательность важна

Если не важна, обходи эту ситуацию известными способами.

> 2) коллизия возможна только

ну ведь возможна же! :)

> групповой инсерт легко регулируется order by в запросе -
> никакой неоднозначности

AFAIR, order by в инсерте недопустим.

> из-за существующего механизма транзакций

А транзакция тут при чем? Речь идет о групповой замене за один присест, в одном операторе.

> и свалили все проблемы на прикладных программистов.

В твоем случае, ты сам вроде как признался, виноваты сами прикладные программисты. Ошибка проектирования базы. Отсюда и проблемы, которые отпали бы, построив базу "правильно".


ANB   (2006-09-05 17:14:00) [28]


> Val ©   (05.09.06 16:58) [47]


> evvcom ©   (05.09.06 17:06) [48]

Так чего же тут нормального ?

Как мы выяснили на примере FB, логического противоречия никакого нет.

Да, если убрать ошибку, то в НЕКОТОРЫХ случаях возможна неоднозначность операции из-за непредсказуемости последовательности обработки строк таблицы при апдейтах и удалениях. Но :
1) далеко не всегда эта последовательность важна
2) коллизия возможна только при групповом обновлении/удалении записей и легко могла бы быть при надобностиликвидирована использованием курсора (групповой инсерт легко регулируется order by в запросе - никакой неоднозначности).

У меня такое впечатление, что оракл просто по техническим причинам (из-за существующего механизма транзакций) не готов работать с измененными/удаленными записями в рамках одного оператора. Посему, чтобы не мучится, сделали генерацию ошибки и свалили все проблемы на прикладных программистов.

Некузяво как то.


evvcom   (2006-09-05 17:06:00) [29]

> [46] ANB ©   (05.09.06 16:52)
> "Мы сделали криво,

Я тоже с этим не согласен. Нормально сделали.


Val   (2006-09-05 16:58:00) [30]

>[46] ANB ©   (05.09.06 16:52)

> "Мы сделали криво...

Это ВЫ так думаете, а кто-то думает иначе. Посоветуете подкрутить сервер под желания каждого разработчика? Да ну его нафиг, такое чудовище.


ANB   (2006-09-05 16:52:00) [31]


> что он будет выполняться также в отдельной транзакции

не в отдельной.


> это описанов доке, в разделе о триггерах, описано и решение.

Ну ктоб спорил. "Мы сделали криво, вот вам руководство, как наши кривые руки обойти на 15 листах".


> evvcom ©   (05.09.06 16:26) [42]

+1.


evvcom   (2006-09-05 16:35:00) [32]

> [41] ANB ©   (05.09.06 16:20)
> Вместо этого могли бы описать эту проблему в доке и не резать
> возможность селекать в своей таблице, когда порядок изменения
> строк не важен

А прикинь, я когда с этим впервые столкнулся, доков на эту тему не читал. Вот умолчал бы Оракл об этом, и я бы долго бы еще тогда пытался понять, почему получаю в селектах не то, что ожидаю. А так полез разбираться и согласился с ними.


evvcom   (2006-09-05 16:32:00) [33]

> [40] ANB ©   (05.09.06 16:18)
> Но к каждому триггеру придется тогда добавить еще и хранимку.

Можно и одну написать, если очень лень, в которой SQL формировать динамически. Кстати, а попробуй динамический SQL прямо в триггере. Есть подозрение, что он будет выполняться также в отдельной транзакции. Не утверждаю, но вдруг? На Оракле я такое еще не проверял.


Val   (2006-09-05 16:30:00) [34]

>[41] ANB ©   (05.09.06 16:20)
это описанов доке, в разделе о триггерах, описано и решение.


evvcom   (2006-09-05 16:26:00) [35]

> [38] ANB ©   (05.09.06 16:13)

Ну да. Здесь функция вызывается для каждой строки при апдейте. Естественно таблица уже меняется.

> [37] Petr V. Abramov ©   (05.09.06 16:12)
> P.S. не люблю триггеры, запутывают они систему, а во-вторых,
> если в случае крайней необходимости надо руками данные
> подправить, может нехорошо получиться

Чтобы обеспечить целостность системы, когда возможностей констрейнтов уже недостаточно, предпочитаю писать триггеры. С триггерами можно и руками подправить, если они корректно написаны. А вот с ХП можно нарваться и на поломку целостности, если кто-то из любителей поправить руками (ну я, например) вдруг не знает, что делать это с данной таблицей категорически запрещается.


ANB   (2006-09-05 16:20:00) [36]


> Вот из-за этой зависимости результата от очередности изменения
> записей Oracle и выдает ошибку про "мутации" :)

Вместо этого могли бы описать эту проблему в доке и не резать возможность селекать в своей таблице, когда порядок изменения строк не важен.


ANB   (2006-09-05 16:18:00) [37]


> См. [27] последнее предложение и [30].

Согласен. Но к каждому триггеру придется тогда добавить еще и хранимку.

> Если базы разные, а потом репликация в главную, мое имхо,
>  лучше сделать составной ПК из id филиала и сиквенса.

1) Базы, есно, разные.
2) Составной PK не сильно кузяво (в связке из 30-40 таблиц да с извратами это сильно неудобно будет)
3) Исторически сложилось, млин. Достаточно было запихать номер филилала в млдашие ращряды ID, а не в старшие (ограничив собственно ID 20000000) и сиквенса бы хватило весьма надолго. Но - см. начало фразы.


evvcom   (2006-09-05 16:17:00) [38]

> [36] kaif ©   (05.09.06 16:04)

Пример кода:
Создаешь TestTable с полями (Id, Value) и такую же LogTable. Вставляешь в TestTable 2 записи (1,1) и (2,1). Далее триггер on TestTable after update on each row:
 insert into LogTable
 select * from TestTable;
Далее выполняешь
update TestTable
 set
   value = value + 1;
и смотришь LogTable. По идее должен получить 4 записи:
(1,2), (2,1), (1,2), (2,2)
или
(1,1), (2,2), (1,2), (2,2)
в зависимости от того, какую запись первой обновит update. Вот из-за этой зависимости результата от очередности изменения записей Oracle и выдает ошибку про "мутации" :)


ANB   (2006-09-05 16:13:00) [39]

Пример (правда бессмысленный) получения ошибки мутации на функции :

create table table2 (ID integer, Parent_ID integer, Status integer)

insert into table2 (ID, Parent_ID, Status)
select rownum, rownum - 1, decode(mod(rownum,2),0,4,5) from dual
connect by level <= 10000

commit;

CREATE OR REPLACE FUNCTION t2_prev_status (p_prev_id INTEGER)
  RETURN INTEGER
AS
  v_status   INTEGER;
BEGIN
  SELECT NVL (MIN (status), 0)
    INTO v_status
    FROM table2
   WHERE ID = p_prev_id;

  RETURN v_status;
END;

select t2.*, t2_prev_status(t2.PARENT_ID) from table2 T2

update table2 T2
set Status = t2_prev_status(t2.PARENT_ID)
where ID = 1

я нарывался на эту ошибку и в реальном проекте. Ох и матов было . . .


> работая из JAVA

Ограничения JDBC/Net. Оракл позволяет управлять уровнем изоляции, но этим мало кто пользуется.


Petr V. Abramov   (2006-09-05 16:12:00) [40]

> 3) И на закузку. Ошибка мутации может вылезти и без триггеров.
 это как Вам удалось??! Научи! :)

> либо вообще изменять данные только через хранимку (там такой проблемы не вылезет).
 вот самое лучшее решение.

> то в триггере производится обращение к своей таблице для проверки дублирования.
 а не эффективнее ли вставки тоже делать хранимкой и действия предпринимать по факту ошибки

P.S. не люблю триггеры, запутывают они систему, а во-вторых, если в случае крайней необходимости надо руками данные подправить, может нехорошо получиться


Страницы:   1 2 3 4

Наверх

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