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

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

Транзакция в TFIBdataset [D7, XP]


Страницы:   1 2

d@nger ©   (2009-10-29 07:57:00) 

Здравствуйте! Я новичек в написании программ под FireBird и сейчас решил перейти с IBX на FIBPlus ... но почему то код работающий на IBX работает не так в FIBPlus. Я добавляю в таблицу запись следующим образом :

with fmain.org_dset do
  try
   insert;
   Fieldbyname('org_id').AsInteger:=fmain.spr_org_query.FieldValues['pk'];
Fieldbyname('org_name').AsString:=fmain.spr_org_query.FieldValues['full_name'];
   Post;
   fmain.my_transaction.CommitRetaining;
 except
  messageDlg('Ошибка при добавлении записи!',mtError,[mbOk], 0);
  fmain.my_transaction.RollbackRetaining;
 end;


поле org_id имеет уникальный индекс... но при добавлении одинакового значения исключение срабатывает, но в DBGrid значение все равно отображается, хотя физически она не добавляется в таблицу. Никак не могу сделать чтобы при возникновении ошибки при добавлении дубля ошибочная строка не отображалась в гриде. Уже все опции FIBDataset пересмотрел... ничего не получается... подскажите что не так... может опцию какую нибудь не выставил..


mKOUZMINE   (2009-11-02 13:34:00) [1]

Cancel не может не срвботать. Где-то промежуточный пост есть. лИБО ЧТО-ТО НЕ ТО


Сергей М.   (2009-10-29 10:28:00) [2]


> если поставит свойство AutoCommit в true, то вызывать Commitretaining
> не надо?


Не надо, если автокоммит правильно настроен (указана нужный объект-транзакция и ее параметры настроены должным образом).
Но при прочих равных условиях предпочтительней все же использовать явноеуправление транзакциями.


> если использовать CancelUpdates то RollBackretaining вызывать
> не обязательно ?


Если нет иного повода для отката транзакции, то не обязательного.


d@nger   (2009-10-29 10:02:00) [3]

а если использовать CancelUpdates то RollBackretaining вызывать не обязательно ?

извените если ушел от темы...


d@nger   (2009-10-29 10:00:00) [4]

спасибо Сергей М. вроде разобрался... буду использовать кэширование и применять ApplyUpdates / CancelUpdates щас проверил.. все работает..

з.ы.  если поставит свойство AutoCommit в true, то вызывать Commitretaining не надо? Проверил без коммита... запись сохранилась..


d@nger   (2009-10-29 09:52:00) [5]


> Приведи дословный текст сообщения об исключении и класс
> исключения ..


---------------------------
Reestr
---------------------------
Fmain.org_dset.InsertQuery:

Can't format message 13:197 -- message file D:\Projects\firebird.msg not found.

Attempt to store duplicate value (visible to active transactions) in unique index "ID_ORG_IDX".

---------------------------
ОК  
---------------------------


Сергей М.   (2009-10-29 09:41:00) [6]


> хочу использовать кэширование


В этом случае синхронизация всехизменений, выполненных тобой в лок.кеше, с соотв.объектами базы данных на стороне сервера выполняется вызовом ApplyUpdates (а отмена всех лок.изменений, соотв-но, вызовом CancelUpdates).

Но тогда не понятна действительная причина возникшего у тебя исключения, ибо судя по dsBrowse оно было вызвано отнюдь не методом Post ..

Приведи дословный текст сообщения об исключении и класс исключения ..


d@nger   (2009-10-29 09:36:00) [7]


> Проверь состояние св-ва дейтасета CachedUpdates (или как
> оно там правильно обзывается - не помню)

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


Сергей М.   (2009-10-29 09:34:00) [8]


> а fmain.my_transaction.RollbackRetaining; разве не делает
> тоже самое?
>


Нет, он занимается сосвем другм - управлением транзакцией.


Сергей М.   (2009-10-29 09:34:00) [9]

Ой, вру)

1 = dsBrowse

Это говорит о том, что исключение вызвал не метод Post, а CommitRetaining.
Что, в свою очередь, говорит о том, что вставка была выполнена успешно лишь в локальномбуфере дейтасета, о чем грид и честно отрапортовал.

Т.е. твой дейтасет, видимо, находится в режиме кешируемых изменений.

Проверь состояние св-ва дейтасета CachedUpdates (или как оно там правильно обзывается - не помню)


d@nger   (2009-10-29 09:33:00) [10]

странно... я вставил showmessage(vartostr(fmain.org_dset.State));перед вызовом insert... что до инсерта что после состояние всегда 1


d@nger   (2009-10-29 09:31:00) [11]


> Т.о. для возвращения грида в исходное состояние следует
> "вручную" вернуть дейтасет из состояния dsInsert в состояние
> dsBrowse, чем как раз и занимается метод Cancel, о чем и
> гласит справка:


а fmain.my_transaction.RollbackRetaining;разве не делает тоже самое?


d@nger   (2009-10-29 09:28:00) [12]

попробовал так:

except
  fmain.org_dset.cancel;
  messageDlg('Ошибка при добавлении записи!',mtError,[mbOk], 0);
  fmain.my_transaction.RollbackRetaining;
  showmessage(vartostr(fmain.org_dset.State));
 end;

выдает 1


d@nger   (2009-10-29 09:25:00) [13]


> Тогда почему на нем висит уникальный индекс? Связь 1:1 что
> ли?


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


Сергей М.   (2009-10-29 09:24:00) [14]


> d@nger   (29.10.09 09:13) [8]


> выдало 1


Это говорит о том, что дейтасет находится в состоянии dsInsert, в которое он перешел при выполнении метода Insert.
Раз так, то наблюдаемое тобой поведение грида вполне нормальное.
Если бы метод Post был выполнен успешно, то дейтасет при этом вернулся бы в состояние dsBrowse, однако этого не произошло по причине возникновения искл.ситуации при выполнении Post.
Т.о. для возвращения грида в исходное состояние следует "вручную" вернуть дейтасет из состояния dsInsert в состояние dsBrowse, чем как раз и занимается метод Cancel, о чем и гласит справка:

As long as those changes are not already posted, Cancel returns the record to its previous state, and sets the dataset state to dsBrowse.
..
If the dataset is not in an editing state (dsEdit or dsInsert), Cancel does nothing


Так что "не сработало" вызывает большие сомнения.


d@nger   (2009-10-29 09:13:00) [15]


> except
> .. чему в этот момент равно fmain.org_dset.State ?? ...
> end;

я проверил так:
 
except
  messageDlg('Ошибка при добавлении записи!',mtError,[mbOk], 0);
  fmain.my_transaction.RollbackRetaining;
  showmessage(vartostr(fmain.org_dset.State));
 end;

выдало 1


Сергей М.   (2009-10-29 09:06:00) [16]

except
.. чему в этот момент равно fmain.org_dset.State ?? ...
end;


Sergey13   (2009-10-29 09:03:00) [17]

> [2] d@nger   (29.10.09 08:54)

Тогда почему на нем висит уникальный индекс? Связь 1:1 что ли?


d@nger   (2009-10-29 09:02:00) [18]

ошибка отображается и Rollbackretaining отрабатывает.. но почему же DBGrid продолжает отображать ошибочную строку... DBGrid.Refresh не помог...org_dset.refresh тоже...


d@nger   (2009-10-29 08:59:00) [19]


>  fmain.org_dset.Cancel;

не сработало


Mike Kouzmine   (2009-10-29 08:57:00) [20]

except
 messageDlg('Ошибка при добавлении записи!',mtError,[mbOk], 0);
 fmain.my_transaction.RollbackRetaining;
 fmain.org_dset.Cancel;
end;


Страницы:   1 2

Наверх

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