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

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

Транзакции в хранимках [MSSQL]


Страницы:   1 2

Ёжик из тумана ©   (2007-02-01 20:29:00) 

Я Вам ещё не надоел?
Тогда Приветствую

У меня в хранимке есть несколько инсертов и вложенная процедура. Так вот всю эту кухню запускать в рамках одной транзакции или на каждое действие по отдельности? Если последнее, то откат будет более длинным (в смысле кода). А откатывать надо целиком всю хранимку. Можно, конечно, с клиента, но зачем лишний траффик гонять?


Bless   (2007-02-08 08:58:00) [1]


> Ega23 ©   (02.02.07 15:21) [26]


Не проверял?


Ёжик из тумана   (2007-02-02 19:36:00) [2]

Ну вот примерно так

begin trans
insert ....

if @@error <> 0
rollback;
return (1);
end

exec @r = procedure

if @r = 1
rollback;
return (2);
end

commit;


evvcom   (2007-02-02 15:38:00) [3]

> [25] Bless ©   (02.02.07 15:21)
> Я так понимаю, ты тоже про rollback?

Я в общем. Про концепцию. И про rollback, и про commit, да какая собственно разница? И без привязки к конкретному серверу, т.к. на MSSQL не практикуюсь.


Bless   (2007-02-02 15:34:00) [4]


> ОК, проверю. Но точно не сегодня, м.б. в выходные. Сейчас
> занят - вилы просто...
> В понедельник отпишусь.


ОК. Раз уж ответ от тебя будет не скоро, а мне сейчас нефиг чем заняться, то я пока обосную свое утверждение :) Собственно, вся аргументация сводится к цитированию справки:

ROLLBACK [ TRAN [ SACTION ]
   [ transaction_name | @tran_name_variable
   | savepoint_name | @savepoint_variable ] ]

Arguments
transaction_name

Is the name assigned to the transaction on BEGIN TRANSACTION. transaction_name must conform to the rules for identifiers, but only the first 32 characters of the transaction name are used. When nesting transactions, transaction_name must be the name from the outermost BEGIN TRANSACTION statement.


Правда непонятно, какая вообще тогда польза от transaction_name.


Ega23   (2007-02-02 15:21:00) [5]


> Имхо, если эта ХП будет вызвана в контексте другой транзакции
> и будет откачена, то будет ошибка на строчке ROLLBACK TRANSACTION
> TranClassDel с сообщением
> Cannot roll back TranClassDel. No transaction or savepoint
> of that name was found.
>
> Я не уверен на все 100 процентов, проверь если можно.


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


Bless   (2007-02-02 15:21:00) [6]


> evvcom ©   (02.02.07 14:30) [20]
>
> Не удивительно, когда понимаешь. А когда не догоняешь, то
> очень даже "удивительно" :)


Я так понимаю, ты тоже про rollback? Тут я не спорю. Кстати говоря, просматривая эту ветку, мне пришла в голову такая мысль:
если в хранимке вместо
BEGIN TRAN
...
DELETE FROM ...
...
ROLLBACK TRAN


написать

IF @@TRANCOUNT>0 SAVE TRAN some_name
ELSE BEGIN TRAN some_name
...
DELETE FROM ...
...
ROLLBACK TRAN some_name


то при вызове этой хранимки в контексе другой транзакции, случись вдруг что, ничего лишнего откачено не будет, вроде, и поведение хранимки перестанет быть "удивительным".
Что скажет народ? Так кто-то делает? Или это бред сивого мерина?


Bless   (2007-02-02 14:56:00) [7]


> Sergey13 ©   (02.02.07 14:48) [22]
>
> > [21] Bless ©   (02.02.07 14:44)
>
> Ты поболтать хочешь? 8-)


Я разговор поддерживаю :о)


Bless   (2007-02-02 14:53:00) [8]


> Ega23 ©   (02.02.07 11:26) [14]


Имхо, если эта ХП будет вызвана в контексте другой транзакции и будет откачена, то будет ошибка на строчке ROLLBACK TRANSACTION TranClassDelс сообщением
Cannot roll back TranClassDel. No transaction or savepoint of that name was found.

Я не уверен на все 100 процентов, проверь если можно.


Sergey13   (2007-02-02 14:48:00) [9]

> [21] Bless ©   (02.02.07 14:44)

Ты поболтать хочешь? 8-)


Bless   (2007-02-02 14:44:00) [10]


> Sergey13 ©   (02.02.07 14:05) [19]
>
> > [18] Bless ©   (02.02.07 14:01)
> А они не связаны?


Это безусловно разные команды.


evvcom   (2007-02-02 14:30:00) [11]

> [16] Bless ©   (02.02.07 12:54)
> А что удивительного?

Не удивительно, когда понимаешь. А когда не догоняешь, то очень даже "удивительно" :)


Sergey13   (2007-02-02 14:05:00) [12]

> [18] Bless ©   (02.02.07 14:01)
А они не связаны?


Bless   (2007-02-02 14:01:00) [13]


> Sergey13 ©   (02.02.07 12:59) [17]
> Попробуй откатить такую транзакцию.


про откатить я знаю :) Но ты ж про commit говорил, а не про rollback.


Sergey13   (2007-02-02 12:59:00) [14]

> [16] Bless ©   (02.02.07 12:54)
> А что удивительного?
Попробуй откатить такую транзакцию.


Bless   (2007-02-02 12:54:00) [15]


> Sergey13 ©   (02.02.07 10:57) [9]
>
> > [7] logic   (02.02.07 10:52)
>
> Оно не мешает. Но вот если, как у автора, ынутри одной процы
> вызывается другая, то если во внутренней будет commit стоять,
>  то вполне можно получить удивление от работы.


А что удивительного?


evvcom   (2007-02-02 11:32:00) [16]

> [12] Sergey13 ©   (02.02.07 11:22)

Согласен. Так еще точнее будет :o)


Ega23   (2007-02-02 11:26:00) [17]

Ну вот пример транзакции в хп:

if @ActNam='CLASSES.DEL'
begin

BEGIN TRANSACTION TranClassDel;

 -- Сначала удалим ClassFields

 exec S_ClassSystem @ActNam='ClassFields.Del', @CLSID=@CLSID, @SelOut=0;
 if @@Error<>0 GoTo ClassesDelRollbackTran;

 -- Теперь удалим ClassMethods

 exec S_ClassSystem @ActNam='ClassMethods.DEL', @CLSID=@CLSID, @SelOut=0;
 if @@Error<>0 GoTo ClassesDelRollbackTran;

  -- Удаляем ClassStates
 exec S_ClassSystem @ActNam='ClassStates.DEL', @CLSID=@CLSID, @SelOut=0;
 if @@Error<>0 GoTo ClassesDelRollbackTran;

 -- Удаляем ClassEvents

 exec S_ClassSystem @ActNam='ClassEvents.DEL', @CLSID=@CLSID, @SelOut=0;
 if @@Error<>0 GoTo ClassesDelRollbackTran;

 -- А теперь и сами Classes

 Delete Classes where CLSID=@CLSID;
 if @@Error<>0 GoTo ClassesDelRollbackTran;

 Select @Result=@CLSID;

ClassesDelCommitTran:
 begin
 if @Debug<>0 print('COMMIT TRANSACTION');
 COMMIT TRANSACTION TranClassDel;

 if @SelOut=1
  begin
  Set NoCount OFF;
  Select Result=@Result;
  end;

 Goto Fin;
 end;

ClassesDelRollbackTran:
 begin
 if @Debug<>0 print('ROLLBACK TRANSACTION');
 ROLLBACK TRANSACTION TranClassDel;
 RaisError('CLASSES.DEL>  ',16,1);
 Return(-1);
 end;

 Goto Fin;

end;


Sergey13   (2007-02-02 11:23:00) [18]

> [11] logic   (02.02.07 11:09)

Это немного не то.


Sergey13   (2007-02-02 11:22:00) [19]

> [10] evvcom ©   (02.02.07 11:00)

В принципе да, это конечная цель. Но одна и та-же ХП может запускаться как отдельно, так и в составе некоего пакета команд, в зависимости от задачи. И тот и другой вариант требует обрамления транзакцией.

Тогда наверное надо сформулировать так. Управление транзакциями должно осуществляться в том же месте программы, где инициализируется начало транзакции.


logic   (2007-02-02 11:09:00) [20]


> Sergey13 ©   (02.02.07 10:57) [9]

Ну вообще-то MSSQL поддерживает вложенные транзакции.
Конечно всегда есть ньюансы, можно почитать тут
http://support.microsoft.com/kb/177138/EN-US/
и тут
http://support.microsoft.com/default.aspx?scid=kb;en-us;198024
Тут все от "рук" разработчика зависит. :)


Страницы:   1 2

Наверх

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