SQL запрос в SQLite - страница 12

 
Maxim Kuznetsov #:

исключительно из требований "быстрый, бесплатный" и опций "легко найти помощь" и "может жить на Linux сервере" (вдруг захочется на хостинг и монстрячить веб-часть)

в списке, при всём богатстве выбора - Postgresql или MySQL , а кто из них - уже на вкус и цвет

MySQL попроще, Postgresql пофичастее

ОК, спасибо

Кажется, сейчас MySQL стала платной

 
Maxim Kuznetsov #:


* как самый крайний случай добавьте RW-Mutex ко всем запросам. Это убьёт скорость напрочь (всё равно что однопоточно), но зато блокировки будут на уровень выше и не вызовут краха.

Это конечно крайний случай, но зато наиболее простой в реализации и позволит с минимальными потерями личного времени двигаться дальше

в делфи (у вас вроде оно), должны быть RWLock , readers-writer-lock

создайте один глобальный RWLock 

и локируйте им вызовы SQLite.. там где только SELECT - это readers, где create/insert/update - writer.

 
Maxim Kuznetsov #:
стой в реализации и позволит с минимальными

Дело не в глобальных локах, а в локах самой базы.

Видимо в SQLite нет ожидания (очереди) обращения к базе 

У меня все запросы "обернуты" в транзакции, что и является локами в базе,

но при обращении к базе большого кол-ва читателей почему-то и возникает конфликт

между трезакциями

Транзакции управляются в ручную

if(MatchStr('FORTS_REFDATA_REPLsession', ExpData.TblsList) = true) then
  begin
    DBConn.StartTransaction;
    try
      FDQuery:= TFDQuery.Create(nil);
      try
        FDQuery.Connection:= DBConn;
        FDQuery.Open('select * from FORTS_REFDATA_REPLsession order by sess_id desc limit 1');
        FDQuery.Last;
        Cnt:= FDQuery.RecordCount;
        if(Cnt > 0) then
        begin
          FDQuery.First;
          FExpData.Session.sess_id:= FDQuery.FieldByName('sess_id').AsInteger;
          FExpData.Session.s_begin:= FDQuery.FieldByName('begin').AsDateTime;
          FExpData.Session.s_end:= FDQuery.FieldByName('end').AsDateTime;
          FExpData.Session.state:= FDQuery.FieldByName('state').AsInteger;
          FExpData.Session.inter_cl_begin:= FDQuery.FieldByName('inter_cl_begin').AsDateTime;
          FExpData.Session.inter_cl_end:= FDQuery.FieldByName('inter_cl_end').AsDateTime;
          FExpData.Session.inter_cl_state:= FDQuery.FieldByName('inter_cl_state').AsInteger;
          FExpData.Session.eve_begin:= FDQuery.FieldByName('eve_begin').AsDateTime;
          FExpData.Session.eve_end:= FDQuery.FieldByName('eve_end').AsDateTime;
          FExpData.Session.mon_on:= FDQuery.FieldByName('mon_on').AsInteger;
          FExpData.Session.mon_begin:= FDQuery.FieldByName('mon_begin').AsDateTime;
          FExpData.Session.mon_end:= FDQuery.FieldByName('mon_end').AsDateTime;
          FExpData.Session.pos_transfer_begin:= FDQuery.FieldByName('pos_transfer_begin').AsDateTime;
          FExpData.Session.pos_transfer_end:= FDQuery.FieldByName('pos_transfer_end').AsDateTime;
        end else
        begin
          FMemoStr:= 'Ошибка! Не получены данные по сессии!';
          Synchronize(UpdMemo);
        end;
      finally
        FDQuery.Free;
      end;
      DBConn.Commit;
    except
      DBConn.Rollback;
    end;
  end;
 

Сами разработчики пишут, что в режиме WAL

Второе преимущество WAL-режима заключается в том, что Писатели не блокируют читателей, а читатели не блокируют писателей.
В основном это так.
Но есть некоторые неясные случаи, когда запрос к WAL-режиму база данных может возвращать SQLITE_BUSY,
поэтому приложения должны быть подготовлены за эту случайность.

Видимо что то не доработали....

 
prostotrader #:

Дело не в глобальных локах, а в локах самой базы.

Видимо в SQLite нет ожидания (очереди) обращения к базе 

У меня все запросы "обернуты" в транзакции, что и является локами в базе,

но при обращении к базе большого кол-ва читателей почему-то и возникает конфликт

между трезакциями

Транзакции управляются в ручную

если сделаешь RWLock на уровне приложения, то появится вожделенная "очередь обращения к базе"...скорость упадёт, но читатели/писатели не будут друг на друга наступать и минимизируются файловые блокировки, практически исчезнут

 
prostotrader #:

Кажется, сейчас MySQL стала платной

Есть популярный форк: MariaDB

Я за Postgresql, но его готовить сложнее. Кстати, там есть варианты выноса временных таблиц на рамдиск.

 
JRandomTrader #:

Есть популярный форк: MariaDB


Я могу использовать только то, что есть в списке на предыдущей странице

Блин, обидно, что прочитал о 

Но есть некоторые неясные случаи, когда запрос к WAL-режиму база данных может возвращать SQLITE_BUSY,

Только сейчас

Неужели разработчики не могли сами сделать "retry" - это же очевидно, не можете найти багу,

сделай повтор запроса.

 
prostotrader #:

Я могу использовать только то, что есть в списке на предыдущей странице

В списке это будет MySQL, а в реале - MariaDB.

Многие Линукс-дистрибутивы по дефолту используют MariaDB вместо MySQL, для приложений это совершенно прозрачно.

 
JRandomTrader #:

В списке это будет MySQL, а в реале - MariaDB.

Многие Линукс-дистрибутивы по дефолту используют MariaDB вместо MySQL, для приложений это совершенно прозрачно.

Я не сам подключаюсь к базе, а посредством FireDAC, если что-то в Марии будет не так,

то нормально работать не будет.

Я почитал сравнение MySQL и PostgreQSL и понятно, что в этом выборе

  PostgreQSL - однозначно! 

Добавлено

Я выбрал SQLite по нескольким причинам:

1. Она есть в списке FireDAC

2. Достаточно быстрая

3. Простая в "разворачивании"

4. Программа для Плаза 2 должна проходить сертификацию 

и "танцы с бубном" им (проверяющим) совсем не нужны 
 

Почувствовала "собака" SQLite, что хочу отказаться, и вот,

уже 3 часа нормально работает :) 

Причина обращения: