Форум: "Базы";
Текущий архив: 2007.07.01;
Скачать: [xml.tar.bz2];
ВнизТранзакции в триггерах Оракла Найти похожие ветки
← →
ANB © (2007-04-04 16:03) [0]Имею :
CREATE TABLE TEST_1
(
ID INTEGER,
F1 VARCHAR2(255 BYTE)
)
create or replace procedure Repl_proc_test_2 (P_id integer)
is
pragma AUTONOMOUS_TRANSACTION;
begin
savepoint Repl_proc_test_2;
null;
/* - сюда хочу воткнуть полезный код
insert into Test_1
(id, F1)
select id*100, F1
from Test_1@Dbmaster
where id = P_id;
*/
exception
when others
then
rollback to Repl_proc_test_2;
end;
CREATE OR REPLACE TRIGGER REP_TRG_TEST_1_S
AFTER INSERT OR UPDATE
ON TEST_1
REFERENCING NEW AS NEW OLD AS OLD
declare
BEGIN
Repl_proc_test_2(2);
END REP_TRG_Test_1_S;
И не могу ничего сделать с таблицей из-за savepoint Repl_proc_test_2;
Причем, если процедуру разместить на другом сервере и вызывать по DBLINK, то все работает, даже без прагмы.
Как обойти эту ерунду ?
← →
ANB © (2007-04-04 16:18) [1]Решение нашел, но неаккуратное.
При использовании прагмы надо обязательно коммит или роллбэк выдавать.
А без прагмы что - никак ? У нас куча хранимок savepoint-ами набита. Получается то, что я сделаю, уже потом никак не откатишь.
← →
Sergey13 © (2007-04-04 16:20) [2]> [0] ANB © (04.04.07 16:03)
А зачем тут savepoint? Делай commit (или просто rollback в исключении). Они вроде должны действовать только на текущую автономку. Из-за этого (вроде) и надо выносить автономку в отдельную процедуру, а не вставлять просто в PL/SQL код.
← →
ANB © (2007-04-04 16:33) [3]
> Sergey13 © (04.04.07 16:20) [2]
Это для примера. На самом деле я должен вызывать хранимки из стандартных пакетов (а они по цепочке еще кучу всего) и везде активно юзаются savepointы.
И как с автономкой правильно делать я уже разобрался. А вот как бы без нее . . .
← →
Sergey13 © (2007-04-04 16:35) [4]> [3] ANB © (04.04.07 16:33)
Не пойму я тебя, Саид. (с) т.Сухов
← →
ANB © (2007-04-04 17:16) [5]
> Sergey13 © (04.04.07 16:35) [4]
Значиться, по событию изменения поля или добавлению записи в таблицу мне нужно проделать некие вещи, реализованные в уже существующих пакетах (довольно сложные и писать их заново как то некузяво). В существующих пакетах активно используются механизмы частичного отката транзакций savepoint/rollback to.
Для отлавливания события я использовал триггера, т.к. отловить все места, где это поле меняется довольно тяжело. Для уменьшения вероятности ошибок (в том числе мутации таблиц) перешел на триггер уровня оператора.
Очень хотелось бы, чтобы все изменения, которые сделают пакеты, работали в контексте общей транзакции сессии, а оракл не дает.
При этом, если повесить дблинк сам на себя и вызывать хранимки по дблинку - все работает. Помогает прагма автономной транзакции, но это не совсем то, что мне нужно.
← →
Val © (2007-04-04 23:35) [6]>Очень хотелось бы, чтобы все изменения, которые сделают пакеты, работали >в контексте общей транзакции сессии, а оракл не дает.
смысл этой фразы для меня, по крайней мере довольно туманен, можно поробнее?
← →
Sergey13 © (2007-04-05 09:11) [7]> [5] ANB © (04.04.07 17:16)
Ты, ИМХО, напоролся на грабли использования управления транзакциями внутри ХП. Если нет четкой логики использования этих ХП (очередность, количество выполняемых ХП), то решить эту проблему - сизифов труд. ИМХО опять же.
← →
ANB © (2007-04-05 11:20) [8]
> смысл этой фразы для меня, по крайней мере довольно туманен,
> можно поробнее?
Есть общий контекст транзакции. Любые DML накапливаются и транзакция должна быть завершена коммитом или роллбэком. Если очень нужно - есть механизм автономных транзакций, т.е. можно что положить в таблицы даже если основную транзакцию откатили.
> Если нет четкой логики использования этих ХП (очередность,
> количество выполняемых ХП), то решить эту проблему - сизифов
> труд.
Да нормальная логика : savepoint / rollback to при ошибке или если очень надо - это в хранимках. Большой и толстый коммит или роллбэк приезжает в конце работы с клиента. Есть другая ?
← →
Val © (2007-04-05 11:34) [9]спасибо за разъяснения :), но меня больше интересовала часть "оракл не дает" и понятие "общая транзакция сессии" лучше бы выкинуть.
← →
ANB © (2007-04-05 11:45) [10]
> но меня больше интересовала часть "оракл не дает"
Пынятно.
Значиться, мне нужно без использования автономной транзакции вызвать из триггера хранимки (а они вызывают по цепочке еще кучу других), в которых есть savepoint/rollback to. Оракл не дает мне это сделать - грит в триггере savepoint делать низзя.
Есть решение, но совсем кривое :
создаю DBLINK на себя же, пишу хранимку, в которой стоят все вызовы других ХП, и эту свою хранимку вызываю не напрямую а через DBLINK. И все работает.
← →
Sergey13 © (2007-04-05 11:47) [11]> [8] ANB © (05.04.07 11:20)
Я так понял что есть уже некоторый функционал написанный на пакетных процедурах, в которых много сейвпоинтов. Ты пытаешься приделать этот функционал в другое место другим способом. И тут эти сейвпоинты выходят из своей обычной логической цепочки и перестают провильно работать. Так?
← →
Кщд © (2007-04-05 11:49) [12]
> Оракл не дает мне это сделать - грит в триггере savepoint
> делать низзя.
увы, в триггере нельзя управлять транзакцией
← →
ANB © (2007-04-05 11:53) [13]
> И тут эти сейвпоинты выходят из своей обычной логической
> цепочки и перестают провильно работать
Они не правильно перестают работать. Они вообще валяться на savepoint.
> увы, в триггере нельзя управлять транзакцией
Через DBLINK - мона.
← →
Кщд © (2007-04-05 12:20) [14]
>
> Через DBLINK - мона.
речь не о наличии возможности, а о самом подходе :)
"...trigger has an autonomous transaction in it
and that is a hugely bad bad bad bad bad idea." Т. Кайт
← →
ANB © (2007-04-05 14:52) [15]
> речь не о наличии возможности, а о самом подходе :)
> "...trigger has an autonomous transaction in it
> and that is a hugely bad bad bad bad bad idea." Т. Кайт
Логически почесав репу - не могу понять - почему в триггере уровня оператора (after) нельзя сделать savepoint и откатиться до него ? Понятно, что commit и обычный rollback - будет не кузяво, а частичный откат почему запрещен ? Тем более внутри одной процедуры ?
И почему мона через DBLINK ? (кстати, при работе через ДБЛИНК и ошибка мутации не валится).
← →
Кщд © (2007-04-05 15:23) [16]
> И почему мона через DBLINK ? (кстати, при работе через ДБЛИНК
> и ошибка мутации не валится).
>
The PL/SQL block of a trigger cannot contain transaction control SQL statements (COMMIT, ROLLBACK, SAVEPOINT, and SET CONSTRAINT) if the block is executed within the same transaction.
а db_link наверняка порождает распределенную транзакцию
т.о. получаете блок savepoint-commit/rollback to - в другой транзакции, отличной от текущей
← →
ANB © (2007-04-05 18:41) [17]
> т.о. получаете блок savepoint-commit/rollback to - в другой
> транзакции, отличной от текущей
Не а. Проверял - логически - в той же. Т.е. если я в хранимке, вызванной по дблинку вставлю куда то запись - она будет видна в этой же сессии без коммита. А при роллбеке - откатится.
А можно ли без дблинка начать "распределенную" транзакцию ?
← →
Кщд © (2007-04-06 05:55) [18]
> Не а. Проверял - логически - в той же. Т.е. если я в хранимке,
> вызванной по дблинку вставлю куда то запись - она будет
> видна в этой же сессии без коммита. А при роллбеке - откатится.
>
можно посмотреть код?
просто любопытно :)
> А можно ли без дблинка начать "распределенную" транзакцию
> ?
непосредственно из серверного кода, насколько я знаю, нет
← →
ANB © (2007-04-06 10:58) [19]
> Кщд © (06.04.07 05:55) [18]
Возьми опубликованный и попробуй вызвать хранимку через ДБЛИНК на свою же схему. Более того - через ДБЛИНК можно безболезненно читать из триггера уровня строки только что добавленную в эту же таблицу незакоммиченную запись и никакой мутации.
> непосредственно из серверного кода, насколько я знаю, нет
Хреново. Может кто прагму подходящую знает ? Через ДБЛИНК работает так, как мне надо - но это же извращение.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.07.01;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c