Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];

Вниз

Транзакция в TFIBdataset   Найти похожие ветки 

 
d@nger   (2009-10-29 07:57) [0]

Здравствуйте! Я новичек в написании программ под 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 пересмотрел... ничего не получается... подскажите что не так... может опцию какую нибудь не выставил..


 
Sergey13 ©   (2009-10-29 08:33) [1]

> [0] d@nger   (29.10.09 07:57)
> поле org_id имеет уникальный индекс...

Это PK для таблицы ORG? Тогда почему туда пишется значение из какого то справочника? Почему не из генератора?


 
d@nger   (2009-10-29 08:54) [2]


> Это PK для таблицы ORG?

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


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

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


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


>  fmain.org_dset.Cancel;

не сработало


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

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


 
Sergey13 ©   (2009-10-29 09:03) [6]

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

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


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

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


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


> 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:24) [9]


> 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:25) [10]


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


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


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

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

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:31) [12]


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


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


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

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


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

Ой, вру)

1 = dsBrowse

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

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

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


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


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


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


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


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

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


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


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


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

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

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


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


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


---------------------------
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".

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


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

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

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


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

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

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


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


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


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


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


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


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

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



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.12.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.005 c
2-1257094427
Don
2009-11-01 19:53
2009.12.20
Как сделать компонент image1 на форме полупрозрачным


6-1209028510
ivanov
2008-04-24 13:15
2009.12.20
3агрузить страницу с подменой своего стиля


2-1256792265
d@nger
2009-10-29 07:57
2009.12.20
Транзакция в TFIBdataset


2-1257241538
EH
2009-11-03 12:45
2009.12.20
Поиск и замена в Excel


2-1256904426
И. Павел
2009-10-30 15:07
2009.12.20
Удаление Objects в TsListBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский