DatabaseTransactionBegin

Начинает выполнение транзакции.

bool  DatabaseTransactionBegin(
   int  database      // хендл базы данных, полученный в DatabaseOpen
   );

Параметры

database

[in]  Хендл базы данных, полученный в DatabaseOpen().

Возвращает true в случае успеха или false, в случае ошибки. Для получения кода ошибки используйте GetLastError(), возможные ответы:

  • ERR_INTERNAL_ERROR (4001)                   –  критическая ошибка исполняющей системы;
  • ERR_INVALID_PARAMETER (4003)              –  параметр sql содержит пустую строку;
  • ERR_NOT_ENOUGH_MEMORY (4004)          –  недостаточно памяти;
  • ERR_WRONG_STRING_PARAMETER (5040)  – ошибка конвертации запроса в UTF-8 строку;
  • ERR_DATABASE_INTERNAL (5120)              – внутренняя ошибка базы данных;
  • ERR_DATABASE_INVALID_HANDLE (5121)   – невалидный хендл базы данных;
  • ERR_DATABASE_EXECUTE (5124)               –  ошибка выполнения запроса.

Примечание

Функцию DatabaseTransactionBegin() необходимо вызывать перед выполнением транзакции. Любая транзакция должна начинаться вызовом DatabaseTransactionBegin() и заканчиваться вызовом DatabaseTransactionCommit().

Пример:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- создадим имя файла
   string filename=AccountInfoString(ACCOUNT_SERVER) +"_"+IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN))+".sqlite";
//--- открываем/создаем базу данных в общей папке терминалов
   int db=DatabaseOpen(filenameDATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
   if(db==INVALID_HANDLE)
     {
      Print("DB: "filename" open failed with code "GetLastError());
      return;
     }
//--- если таблица DEALS уже есть, удалим её
   if(!DeleteTable(db"DEALS"))
     {
      DatabaseClose(db);
      return;
     }
//--- создадим таблицу DEALS
   if(!CreateTableDeals(db))
     {
      DatabaseClose(db);
      return;
     }
//---  запросим всю торговую историю
   datetime from_date=0;
   datetime to_date=TimeCurrent();
//--- запросим историю сделок в указанном интервале
   HistorySelect(from_dateto_date);
   int deals_total=HistoryDealsTotal();
   PrintFormat("Торговая история насчитывает сделок: %d "deals_total);
 
//--- замерим скорость выполнения транзакций с использованием DatabaseTransactionBegin/DatabaseTransactionCommit
   ulong start=GetMicrosecondCount();
   bool fast_transactions=true;
   InsertDeals(dbfast_transactions);
   double fast_transactions_time=double(GetMicrosecondCount()-start)/1000;
   PrintFormat("Transations WITH    DatabaseTransactionBegin/DatabaseTransactionCommit: time=%.1f milliseconds"fast_transactions_time);
 
//--- удалим таблицу DEALS - будем создавать её заново
   if(!DeleteTable(db"DEALS"))
     {
      DatabaseClose(db);
      return;
     }
//--- создадим заново таблицу DEALS
   if(!CreateTableDeals(db))
     {
      DatabaseClose(db);
      return;
     }
 
//--- сделаем тест заново без использования DatabaseTransactionBegin/DatabaseTransactionCommit
   fast_transactions=false;
   start=GetMicrosecondCount();
   InsertDeals(dbfast_transactions);
   double slow_transactions_time=double(GetMicrosecondCount()-start)/1000;
   PrintFormat("Transations WITHOUT DatabaseTransactionBegin/DatabaseTransactionCommit: time=%.1f milliseconds"slow_transactions_time);
//--- сообщим выигрыш по времени
   PrintFormat("Использование DatabaseTransactionBegin/DatabaseTransactionCommit дало ускорение в %.1f раз"double(slow_transactions_time)/fast_transactions_time);
//--- закрываем базу данных
   DatabaseClose(db);
  }
/*
Результат:
   Торговая история насчитывает сделок: 2737 
   Transations WITH    DatabaseTransactionBegin/DatabaseTransactionCommittime=48.5 milliseconds
   Transations WITHOUT DatabaseTransactionBegin/DatabaseTransactionCommittime=25818.9 milliseconds
   Использование DatabaseTransactionBegin/DatabaseTransactionCommit дало ускорение в 532.8 раз
*/
//+------------------------------------------------------------------+
//| Удаляет из базы таблицу с указанным именем                       |
//+------------------------------------------------------------------+
bool DeleteTable(int databasestring table_name)
  {
   if(!DatabaseExecute(database"DROP TABLE IF EXISTS "+table_name))
     {
      Print("Failed to drop table with code "GetLastError());
      return(false);
     }
//--- таблица успешно удалена
   return(true);
  }
//+------------------------------------------------------------------+
//| Создает таблицу DEALS                                            |
//+------------------------------------------------------------------+
bool CreateTableDeals(int database)
  {
//--- проверим наличие таблицы
   if(!DatabaseTableExists(database"DEALS"))
      //--- создаем таблицу
      if(!DatabaseExecute(database"CREATE TABLE DEALS("
                          "ID          INT KEY NOT NULL,"
                          "ORDER_ID    INT     NOT NULL,"
                          "POSITION_ID INT     NOT NULL,"
                          "TIME        INT     NOT NULL,"
                          "TYPE        INT     NOT NULL,"
                          "ENTRY       INT     NOT NULL,"
                          "SYMBOL      CHAR(10),"
                          "VOLUME      REAL,"
                          "PRICE       REAL,"
                          "PROFIT      REAL,"
                          "SWAP        REAL,"
                          "COMMISSION  REAL,"
                          "MAGIC       INT,"
                          "REASON      INT );"))
        {
         Print("DB: create the table DEALS failed with code "GetLastError());
         return(false);
        }
//--- таблица успешно создана
   return(true);
  }
//+------------------------------------------------------------------+
//| Вносит сделки в таблицу базы данных                              |
//+------------------------------------------------------------------+
bool InsertDeals(int databasebool begintransaction=true)
  {
//--- вспомогательные переменные
   ulong    deal_ticket;         // тикет сделки
   long     order_ticket;        // тикет ордера,по которому была совершена сделка
   long     position_ticket;     // ID позиция, к которой относится сделка
   datetime time;                // время совершения сделки
   long     type ;               // тип сделки
   long     entry ;              // направление сделки
   string   symbol;              // по какому символу была сделка
   double   volume;              // объем операции
   double   price;               // цена
   double   profit;              // финансовый результат
   double   swap;                // своп
   double   commission;          // комиссия
   long     magic;               // Magic number
   long     reason;              // причина или источник проведения сделки
//--- пройдем по всем сделкам и внесем в базу данных
   bool failed=false;
   int deals=HistoryDealsTotal();
//--- если используется быстрый способ проведения транзакций
   if(begintransaction)
     {
      //--- заблокируем базу данных перед выполнением транзакций
      DatabaseTransactionBegin(database);
     }
   for(int i=0i<dealsi++)
     {
      deal_ticket=    HistoryDealGetTicket(i);
      order_ticket=   HistoryDealGetInteger(deal_ticketDEAL_ORDER);
      position_ticket=HistoryDealGetInteger(deal_ticketDEAL_POSITION_ID);
      time= (datetime)HistoryDealGetInteger(deal_ticketDEAL_TIME);
      type=           HistoryDealGetInteger(deal_ticketDEAL_TYPE);
      entry=          HistoryDealGetInteger(deal_ticketDEAL_ENTRY);
      symbol=         HistoryDealGetString(deal_ticketDEAL_SYMBOL);
      volume=         HistoryDealGetDouble(deal_ticketDEAL_VOLUME);
      price=          HistoryDealGetDouble(deal_ticketDEAL_PRICE);
      profit=         HistoryDealGetDouble(deal_ticketDEAL_PROFIT);
      swap=           HistoryDealGetDouble(deal_ticketDEAL_SWAP);
      commission=     HistoryDealGetDouble(deal_ticketDEAL_COMMISSION);
      magic=          HistoryDealGetInteger(deal_ticketDEAL_MAGIC);
      reason=         HistoryDealGetInteger(deal_ticketDEAL_REASON);
      //--- внесем каждую сделку через запрос
      string request_text=StringFormat("INSERT INTO DEALS (ID,ORDER_ID,POSITION_ID,TIME,TYPE,ENTRY,SYMBOL,VOLUME,PRICE,PROFIT,SWAP,COMMISSION,MAGIC,REASON)"
                                       "VALUES (%d, %d, %d, %d, %d, %d, '%s', %G, %G, %G, %G, %G, %d, %d)",
                                       deal_ticket, order_ticket, position_tickettimetypeentrysymbolvolumepriceprofitswapcommissionmagicreason);
      if(!DatabaseExecute(databaserequest_text))
        {
         PrintFormat("%s: failed to insert deal #%dwith code %d"__FUNCTION__deal_ticketGetLastError());
         PrintFormat("i=%d: deal #%d  %s"ideal_ticket, symbol);
         failed=true;
         break;
        }
     }
//--- проверим на наличие ошибок при выполнении транзакций
   if(failed)
     {
      //--- если используется быстрый способ проведения транзакций
      if(begintransaction)
        {
         //--- откатим все транзакции и разблокируем базу данных
         DatabaseTransactionRollback(database);
        }
      Print("%s: DatabaseExecute() failed with code "__FUNCTION__GetLastError());
      return(false);
     }
//--- если используется быстрый способ проведения транзакций
   if(begintransaction)
     {
      //--- все транзакции прошли успешно - зафиксируем изменения и разблокируем базу данных
      DatabaseTransactionCommit(database);
     }
//--- успешное завершение
   return(true);
  }
//+------------------------------------------------------------------+

Смотри также

DatabaseExecute, DatabasePrepare, DatabaseTransactionCommit, DatabaseTransactionRollback