Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
Хотел бы в целях профессионального роста научиться работать с FireDAC и читающими и короткими пищущими транзакциями.
Итак, есть например, таблица заказов ORDERS. Есть FDQuery1, который настроен на читающую транзакцию. Есть UpdateSQL, в котором описаны основные DML операторы и подключена пишущая неавтостартующая транзакция. Использовать встроенный в FDQuery механизм работы с DML не получается, так как есть автоинкрементные поля, которые заполняет сервер, а FDQuery не дает их оставлять пустыми, несмотря на отключаемые CheckRequiered.
Посему вопрос - как красиво и академически правильно работать с FDQuery и SQLUpdate, чтоб после добавления или изменения записи не перезагружать весь FDQuery, а обновлять только измененные записи? Я так понимаю, можно задействовать FDMEmTable, но не могу понять - как этот зверинец заставить вместе работать, чтоб они были тандемом, а не отдельно работающими компонентами. Раньше с IBDAC работал - там как-то полюдски сделано - в одном IBCQuery можно было задать и читающий оператор, и модифицирующие, причем с возвращаемыми параметрами. И отлично работало игнорирование автоинкрементных полей.

Спасибо за любые наводки
4 авг 19, 17:52    [21941623]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
ёёёёё
Member

Откуда:
Сообщений: 580
GrigoriyFomin,

на хабре были примеры приложений 'фаерберд через фаердак'.

Пожалуйсто. :)
4 авг 19, 17:55    [21941626]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47957

GrigoriyFomin
Хотел бы в целях профессионального роста научиться работать с FireDAC и читающими и
короткими пищущими транзакциями.

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

Posted via ActualForum NNTP Server 1.5

4 авг 19, 17:55    [21941627]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
RADSeatle
Member

Откуда:
Сообщений: 126
Вот тут почитайте
https://habr.com/ru/post/273549/
5 авг 19, 07:54    [21941809]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
Статью эту читал, жаль, единственная статья по этой теме. Но у меня остался непонятной ситуация.
Есть таблица заказов, есть подчиненная таблица пунктов заказа (классика мастер-детеил).
2 запроса с селектами и 2 UpdateSQL с соответствующими процедурами DML. Для обоих датасетов стоит CacheUpdates.
Вопрос №1 - как не выдавать ошибку при добавлении новой записи, учитывая, что FB 3.0 и стоит автоинкрементное поле нового типа (без генератора)
Вопрос №2 - как детейлед таблице указать OrderID мастер-таблицы, если ИД мастера будет выявлен лишь после ApplyUpdates? Можно генератор прописать и тогда FDQuery будет сам заполнять это поле, но как быть с автоинкрементным полем без генератора?
7 авг 19, 23:01    [21944204]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
Vlad F
Member

Откуда:
Сообщений: 868
GrigoriyFomin,

За это все, в принципе, какую-то зарплату платят или всё-таки курсовая?
7 авг 19, 23:15    [21944212]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
Vlad F

За это все, в принципе, какую-то зарплату платят или всё-таки курсовая?

Платят, но не за это. Это в целях повышения самообразования и желания перейти на FireDAC в будущем.
Вот уже со многим разобрался, а как работать с автоинкрементными полями, когда они ключевые и используются для связки мастер-детейл - не могу.
7 авг 19, 23:24    [21944218]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
ёёёёё
Member

Откуда:
Сообщений: 580
GrigoriyFomin
...Вопрос №1 - как не выдавать ошибку при добавлении новой записи, учитывая, что FB 3.0 и стоит автоинкрементное поле нового типа (без генератора)
Вопрос №2 - как детейлед таблице указать OrderID мастер-таблицы, если ИД мастера будет выявлен лишь после ApplyUpdates? Можно генератор прописать и тогда FDQuery будет сам заполнять это поле, но как быть с автоинкрементным полем без генератора?


+


Непонятно, ради чего так над собой изгаляться. В "штатных" IBX и "нештатных" FIB+ все "проблемы" давным-давно решены и многократно описаны. Я буквально сегодня начал новый проект с FB 3.0, используя древние FIB+ V6.9.9 - пока не вижу никаких проблем. Если понадобится какая-нибудь новая фича - перейду "новые" на фибы с гитхаба, или допилю старые.

Даю 99%, что тебе никто не поможет. Разве что сам Арефьев.
7 авг 19, 23:26    [21944219]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
ёёёёё,

Хорошо. Сузю задачуу
1. Стартанули пишущую транзакцию.
2. сохранили мастер запись ApplyUpdates.
3. как узнать значение автоинкрементного поля после этого? Выдает 0.
4. перебираем ранее добавленные детейл записи и присваиваем ИД родителя - полученное в шаге №3 ИД.
5. Для детейл датасета делаем ApplyUpdates.
6. Коммитим транзакцию.

Что я делаю не так? )
вариант использовать генератор оставляю на последок как выход из безвыходной ситуации.
7 авг 19, 23:35    [21944224]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
Vlad F
Member

Откуда:
Сообщений: 868
GrigoriyFomin,

Так конкретные проблемы твои без исходников до конца не понятны.
В качестве утешения могу твердо заверить, что и на FireDAC абсолютно все это, умеючи, сделать возможно.))
7 авг 19, 23:35    [21944225]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
ёёёёё
Member

Откуда:
Сообщений: 580
GrigoriyFomin,

да кто, кроме тебя, знает, что ты не так делаешь. Может, ты returning в insert не добавил. Все, что угодно может быть.

Что там у тебя за код и скрипт? Поди догадайся.
7 авг 19, 23:39    [21944228]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
Vlad F,

  qBIDS.Append;
//Заполняем мастер-запись
...
  qBIDS.FieldByName('BCAID').AsInteger:=edrCAID.Properties.Value;
...
  qBIDS.post;
  trsOrdWr.StartTransaction;
  try
    qBIDS.ApplyUpdates;
//vvvvvvvvvvv
    BID:=qBIDS.FieldByName('BID').AsLargeInt; //Хотим тут сохранить присвоенное сервером значение автоинкрементного поля
//^^^^^^^^ вот ключевая строка - значение аввтоинкрементного поля - 0. Делать коммит? 
// а если на следующих строках будет ошибка? мастер запись останется, детейлы - нет

//Хотим перебрать детейл-записи и прописать у них ИД родительской мастер-записи
    qBIS.First;
    while not qBIS.eof do
    begin
      qBIS.Edit;
      qBIS.FieldByName('BIBID').AsLargeInt:=BID;
      qBIS.Post;
      qBIS.next;
    end;
    qBIS.ApplyUpdates;
    trsOrdWr.Commit;
except
    trsOrdWr.Rollback;
end
7 авг 19, 23:44    [21944230]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
ёёёёё
Member

Откуда:
Сообщений: 580
GrigoriyFomin,

"Кисочка, миленькая, ну ещё хоть капельку..." - (с).

Теперь insert предложение покажи. И DDL таблички.
------
Конечно, Commit после master - записи делать не стоит, в любом случае. У тебя же составной документ. Только после успешной заливки деталей.
7 авг 19, 23:48    [21944232]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
ёёёёё
GrigoriyFomin,

да кто, кроме тебя, знает, что ты не так делаешь. Может, ты returning в insert не добавил. Все, что угодно может быть.

Что там у тебя за код и скрипт? Поди догадайся.

в returning поля прописаны. Меня интересует правильный академичсекий подход, задача-то типовая - как сохранить мастер и детейл записи при автоинкрементном связующем поле и CachedUpdates.
7 авг 19, 23:48    [21944233]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
ёёёёё
Member

Откуда:
Сообщений: 580
GrigoriyFomin
ёёёёё
GrigoriyFomin,

да кто, кроме тебя, знает, что ты не так делаешь. Может, ты returning в insert не добавил. Все, что угодно может быть.

Что там у тебя за код и скрипт? Поди догадайся.

в returning поля прописаны. Меня интересует правильный академичсекий подход, задача-то типовая - как сохранить мастер и детейл записи при автоинкрементном связующем поле и CachedUpdates.


Ну, раз ты все делаешь как надо - ошибка в компонентах, а что ж ещё.
7 авг 19, 23:50    [21944235]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
ёёёёё
"Кисочка, миленькая, ну ещё хоть капельку..." - (с).

Теперь insert предложение покажи. И DDL таблички.
------
INSERT INTO BIDS
(BCAID, BFROM, BTO, BDATE, BDEADLINE, 
  BEXECUTED, BCANCELED, BEMPSTART, BEMPEXEC, 
  BEMPEND, BNOTES, BTYPE, BRESULT, BPRIORITY, 
  BSTART, BEND, BADR, BNAME, BPHONE, 
  BPAYTYPE, BADD, BPREPAYED, BPREPAYSUM, 
  BSTATUS, BORDERID)
VALUES (:NEW_BCAID, :NEW_BFROM, :NEW_BTO, :NEW_BDATE, :NEW_BDEADLINE, 
  :NEW_BEXECUTED, :NEW_BCANCELED, :NEW_BEMPSTART, :NEW_BEMPEXEC, 
  :NEW_BEMPEND, :NEW_BNOTES, :NEW_BTYPE, :NEW_BRESULT, :NEW_BPRIORITY, 
  :NEW_BSTART, :NEW_BEND, :NEW_BADR, :NEW_BNAME, :NEW_BPHONE, 
  :NEW_BPAYTYPE, :NEW_BADD, :NEW_BPREPAYED, :NEW_BPREPAYSUM, 
  :NEW_BSTATUS, :NEW_BORDERID)
RETURNING /*вот автоинкрементное поле от сервера*/BID,/*будь оно не ладно */ DBDATE, BPRIORITY, _BFROMNAME, _BTONAME, _BCANAME, _EMPSTART, _EMPEXEC, _EMPEND, _PAYTYPE, _BTYPE, _PRIORITY, BSTATUS, _STATUS, _ITEMS

вот как описана таблица
CREATE TABLE BIDS (
    BID           D_REGID GENERATED BY DEFAULT AS IDENTITY /* D_REGID = BIGINT NOT NULL */,
    BCAID         D_ID /* D_ID = INTEGER NOT NULL */,
    BFROM         D_ID NOT NULL /* D_ID = INTEGER NOT NULL */,
    BTO           D_ID /* D_ID = INTEGER NOT NULL */,
    BDATE         D_TS /* D_TS = TIMESTAMP */,
    BDEADLINE     D_TS /* D_TS = TIMESTAMP */,
    BEXECUTED     D_TS /* D_TS = TIMESTAMP */,
    BCANCELED     D_TS /* D_TS = TIMESTAMP */,
    BEMPSTART     D_ID /* D_ID = INTEGER NOT NULL */,
    BEMPEXEC      D_ID /* D_ID = INTEGER NOT NULL */,
    BEMPEND       D_ID /* D_ID = INTEGER NOT NULL */,
    DBDATE        D_TS DEFAULT current_timestamp NOT NULL /* D_TS = TIMESTAMP */,
    BNOTES        D_TB /* D_TB = BLOB SUB_TYPE 1 SEGMENT SIZE 80 */,
    BTYPE         D_ID /* D_ID = INTEGER NOT NULL */,
    BRESULT       D_ID /* D_ID = INTEGER NOT NULL */,
    BPRIORITY     D_ID DEFAULT 1 NOT NULL /* D_ID = INTEGER NOT NULL */,
    BSTART        D_TS /* D_TS = TIMESTAMP */,
    BEND          D_TS /* D_TS = TIMESTAMP */,
    BADR          D_NAME /* D_NAME = VARCHAR(100) */,
    BNAME         D_NAME /* D_NAME = VARCHAR(100) */,
    BPHONE        D_NAME /* D_NAME = VARCHAR(100) */,
    BPAYTYPE      D_ID /* D_ID = INTEGER NOT NULL */,
    BADD          D_PATH /* D_PATH = VARCHAR(1000) */,
    BPREPAYED     D_TS /* D_TS = TIMESTAMP */,
    BPREPAYSUM    D_SUM /* D_SUM = DECIMAL(18,2) */,
    "_BFROMNAME"  COMPUTED BY ((select caname from cas where caid=bfrom)),
    "_BTONAME"    COMPUTED BY (((select caname from cas where caid=bto))),
    "_BCANAME"    COMPUTED BY (((select caname from cas where caid=bcaid))),
    "_EMPSTART"   COMPUTED BY ((select caname from cas where bEMPSTART=caid)),
    "_EMPEXEC"    COMPUTED BY ((select caname from cas where bEMPexec=caid)),
    "_EMPEND"     COMPUTED BY ((select caname from cas where bEMPEND=caid)),
    "_PAYTYPE"    COMPUTED BY ((select ptname from paytypes where ptid=bpaytype)),
    "_BTYPE"      COMPUTED BY ((select btname from bidtypes where btid=btype)),
    "_PRIORITY"   COMPUTED BY ((select prname from priorities where prid=bpriority)),
    BSTATUS       D_ID DEFAULT 1 NOT NULL /* D_ID = INTEGER NOT NULL */,
    "_STATUS"     COMPUTED BY ((select bsname from bidstatus where bstatus=bsid)),
    "_ITEMS"      BLOB SUB_TYPE 1 COMPUTED BY ((select list("_BRIEFART" || ': ' || BICNT, ascii_char(13)) as BI 
from BIDIT where BIBID = BID)),
    BORDERID      D_BIGINT /* D_BIGINT = BIGINT */
);


7 авг 19, 23:52    [21944236]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
ёёёёё
GrigoriyFomin
пропущено...

в returning поля прописаны. Меня интересует правильный академичсекий подход, задача-то типовая - как сохранить мастер и детейл записи при автоинкрементном связующем поле и CachedUpdates.


Ну, раз ты все делаешь как надо - ошибка в компонентах, а что ж ещё.

Так я как раз и понимаю, что я делаю то-то не так - хочу разобраться. Раз задача тривиальная, значит решение есть бескостыльное и красивое. А найти его не получается, для чего на форуме и вопрошаю )
7 авг 19, 23:55    [21944238]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите концепцию работы с FIREDAC и "правильными транзакциями"  [new]
GrigoriyFomin
Member

Откуда:
Сообщений: 12
Поигрался со свойствами датасетов и вроде как получил теперь ИД мастер-записи (сам не понял, правда, как). Как теперь этот ИД прописать в детеил записях?
8 авг 19, 00:22    [21944245]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить