Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2012, 15:30   #1
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию write-транзакция в MyDAC

Как в MyDAC организовать транзакцию на несколько команд Insert?
В БД только разбираюсь, пробую так:
Код:
try
  FdbConn.StartTransaction;
  for i:=0 to LsTempList.Count-1 do
  begin
    FdbQuery.SQL.Text:=LsTempList[i];
    FdbQuery.ExecSQL;
  end;
  FdbConn.Commit;
except
  FdbConn.Rollback;
end;
Код не работает, в БД ничего не пишется. Поправьте меня пожалуйста и по возможности, киньте ссылками на соответствующую тему прилагательно к Delphi. Спасибо!
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 01.03.2012, 21:17   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А что значит код не работает? Вываливает ошибку или все Ok, а в базе пусто? Если ошибка, то на какой команде? Кстати сам метод StartTransaction может исключение вызвать и тогда в except вызов Rollback тоже исключение поднимет со всеми вытекающими последствиями. Я к тому, что StartTransaction нужно в отдельный try ... except оформлять.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.03.2012, 21:23   #3
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Код вываливает ошибку, причем молчаливого типа. Поток создается, инициализируется, пытается выполнить функцию с этим кодом. Функцию возвращает false. Поток проверяет результат и в случае краха уничтожается с закрытием соединения и уничтожением всех своих объектов.
Поясните пожалуйста, почему StartTransaction требует отдельного контроля? И корректен ли вообще приведенный мною код?
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 01.03.2012, 21:36   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Основное назначение StartTransaction послать в СУБД соответствующую SQL-команду старта транзакции, которая по разным причинам может не выполниться. Хотя бы из-за того, что соединение разорвано. Вот и возможная причина исключения. В остальном на глаз не вижу проблем. Точно установите на какой команде проблема. Возможно причина в содержимом LsTempList. Можно показать какие там команды?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 01.03.2012 в 22:03.
Аватар вне форума Ответить с цитированием
Старый 02.03.2012, 20:31   #5
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

В этот список помещаются запросы на выполнение. Все запросы корректы. Специально их логгировал в файл и выполнял на той же БД в навикате. Суть в том, что при комментировании этих 3х строк с StartTransaction, Commit и Rollback код работает сутками 24/7. Но дело в том что выполняется несколько инсертов в цикле в этой функции, которая считается атомарной по логике приложения. Если не выполнятся не все запросы по разным причинам, то данные в них будут потеряны. Потому и встала задача толкать список инсертов транзакцией.
Код функции записи в БД:
Код:
//записывает в БД результаты запросов ASQLQuery (если удалось, то true)
function SaveDB(const ASQLQuery:AnsiString):Boolean;
...
function TTCPClientThread.SaveDB(const ASQLQuery:AnsiString):Boolean;
var
  i:Integer;
  LsTempList:TStringList;
begin
  Result:=True;
  try
    //если нет подключения к БД, подключаемся
    if (not FdbConn.Connected) then
    with FdbConn,gConfig do
    begin
      try
        Lock;
          Username:=FdbLogin;
          Password:=FdbPass;
          Server:=FdbIP;
          Port:=StrToInt(FdbPort);
          Database:=FdbName;
      finally
        Unlock;
      end;
    end;

    //запись в БД
    try
      LsTempList:=TStringList.Create;
      LsTempList.Text:=ASQLQuery;
//      FdbConn.StartTransaction;
      for i:=0 to LsTempList.Count-1 do
      begin
        FdbQuery.SQL.Text:=LsTempList[i];
        FdbQuery.ExecSQL;
      end;
//      FdbConn.Commit;
    finally
      FreeAndNil(LsTempList);
    end;
  except
    Result:=False;
//    FdbConn.Rollback;
    FOwner.ErrLog('TTCPClientThread.SaveDB'#13#10'Query: '+ASQLQuery);
  end;
end;
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 02.03.2012, 20:34   #6
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Запросы формируются по константным маскам методом наращивания:
Код:
const
  cntGpsQueryMask:AnsiString=//маска формирования запроса для таблицы
                  'INSERT INTO `gps` '+
{0}               '(`equip_id`'+
{1}               ',`gps_imei`'+
{const}           ',`gps_fix`'+
{2}               ',`gps_date`'+
{3}               ',`gps_time`'+
{4}               ',`gps_lon`'+
{5}               ',`gps_lat`'+
{6}               ',`gps_alt`'+
{7}               ',`gps_speed`'+
{8}               ',`gps_sat`'+
{9}               ',`gps_kurs`'+
{10}              ',`signal_level`) '+
                  'VALUES (%s,%s,''0'',%s,%s,%s,%s,%s,%s,%s,%s,%s)';

  cntAnlQueryMask:AnsiString=//маска формирования запроса для таблицы
                  'INSERT INTO `data_sens_anal` '+
{0}               '(`equip_id`'+
{const}           ',`equip_num`'+
{1}               ',`date`'+
{2}               ',`time`'+
{3}               ',`indication`'+
{4}               ',`indication1`'+
{5}               ',`indication2`) '+
                  'VALUES (%s,''1'',%s,%s,%s,%s,%s)';

  cntDigQueryMask:AnsiString=//маска формирования запроса для таблицы
                  'INSERT INTO `data_sens_dig` '+
{0}                '(`equip_id`'+
{const}            ',`equip_num`'+
{1}                ',`date`'+
{2}                ',`time`'+
{3}                ',`state`'+
{4}                ',`state1`'+
{5}                ',`state2`'+
{6}                ',`state3`'+
{7}                ',`counter1`'+
{8}                ',`counter2`'+
{9}                ',`counter3`'+
{10}               ',`counter4`) '+
                   'VALUES '+
                   '(%s,''1'',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)';
Маски корректные, код проверен, отлажен и в стадии тестирования. Интересует выполнение транзакций. По коммерческим причинам не могу привести больше кода. Скажу лишь, что проблем с ним нет, все работает отлично. Тест идет уже 4е сутки без перебоев. Таблицы в БД на движке InnoDB, поддержка транзакций присутствует.
Что можете посоветовать? Может есть какие-то особенности по работе именно с MyDAC?
"ковыряю изнутри" (с)

Последний раз редактировалось 3D Hunter; 02.03.2012 в 20:39.
3D Hunter вне форума Ответить с цитированием
Старый 03.03.2012, 22:26   #7
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Если кто-нибудь работает с MyDAC, скажите пожалуйста, как правильно реализововать транзакцию? Возможно, через MyCommand вместо MyQuery?
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 05.03.2012, 14:45   #8
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Проблема решена, тема закрыта.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
MyDAC zumm Компоненты Delphi 0 18.12.2011 15:37
Установка компонента MyDac GreenShuller БД в Delphi 7 17.05.2011 13:23
Документация к MyDac Detka.i.alex Помощь студентам 0 13.04.2011 20:59
MyDAC и FastReport lyle_200490 БД в Delphi 2 20.11.2010 20:58
MyDAC Antoha Компоненты Delphi 1 08.06.2010 14:36