Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Bulgarian
  4. [Решен] Постоянна mysql връзка
QtWS25 Last Chance

[Решен] Постоянна mysql връзка

Scheduled Pinned Locked Moved Bulgarian
5 Posts 2 Posters 6.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robbin
    wrote on 26 Aug 2013, 10:42 last edited by
    #1

    Здравейте.

    Вече в няколко проекта срещам проблем със свързаността към mysql.
    Не намирам никакъв начин за проверка дали връзката към базата не се е разпаднала преди да се изпълни заявка. Направил съм следното:
    @
    QSqlDatabase Common::getDatabase()
    {
    QSqlDatabase db;
    if( QSqlDatabase::contains("connname") && QSqlDatabase::database("connname").isValid() ) {
    db = QSqlDatabase::database("connname");
    } else {
    db = QSqlDatabase::addDatabase("QMYSQL", "connname");
    db.setHostName("dhhost");
    db.setDatabaseName("connname");
    db.setUserName("dbuser");
    db.setPassword("dbpass");
    db.open();
    }

    return db;
    

    }
    @

    Класа "Common" има само статични методи, с идеята да мога да ги викам от всяка част на програмата, без да правя обекти само заради една функция. Ползвам го по следния начин:
    @
    QSqlQuery query( Common::getDatabase() );
    query.exec("SELECT * FROM `table");
    @

    Когато връзката към базата не е нарушена от пускането на програмата до спирането и, всичко е наред и с тези функции работят нещата. Но ако връзката прекъсне (свързване към друг доставчик, VPN, спиране на мрежов кабел и други), програмата чака query.exec да приключи, който пък не може да приключи заради нарушената връзка. Търсих какви ли не варианти, isValid() и isOpen() на QSqlDatabase винаги връщат true и с тях не може да се проверява състоянието на връзката.
    Някой от вас намерил ли е решение на този проблем? Единственото което ми идва на ум е да направя wrapper клас който да викам при нови заявки към базата и в него да стартирам конекцията и да я спирам веднага след като заявката приключи. Това разбира се ще дойде и с големия overhead за отваряне на нова конекция всеки път и според мен не е решение. Едва ли във всеки един момент ще имам повече от 1 заявка работеща на дадената връзка, така че метода е възможен, но ме притеснява "разхода" на ресурси и скоростта на работа.

    1 Reply Last reply
    0
    • T Offline
      T Offline
      task_struct
      wrote on 26 Aug 2013, 13:59 last edited by
      #2

      Здравей,

      и аз си играя с подобни неща за дипломната ми работа. Не съм ги тествал, защото така и няма да ме накарат да я пусна :D

      Но като цяло за мрежата може да следиш с @QNetworkAccessManager::networkAccessibleChanged@ Според документацията е добре всяка програма да има само една инстанция на QNetworkAccessManager за това аз си го правя глобална променлива и си я достъпвам от където ми трябва. При този сигнал, когато се появи мрежа може да отваряш базата на ново.

      Друго, което мога да те посъветвам е за QSqlDatabase e, да не правиш допълнителен клас.

      Можеш спокойно в main преди да стартираш всичко да извикаш @QSqlDatabase db = QSqlDatabase::addDatabase( "QMYSQL", "connname" );@ Това ще съдаде DB с такова име в някакъв глобален лист. После може да си я достъпваш от там с @QSqlDatabase db = QSqlDatabase::database("connname");@
      Още след създаването на базата и подаваш:
      @
      db.setHostName("dhhost");
      db.setDatabaseName("connname");
      db.setUserName("dbuser");
      db.setPassword("dbpass");
      @
      От там нататък той си ги знае и само ще викаш open(), когато се появи пак връзка. По-чисто ще стане така, според мен ;)

      "Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."

      • Linu...
      1 Reply Last reply
      0
      • R Offline
        R Offline
        Robbin
        wrote on 27 Aug 2013, 06:10 last edited by
        #3

        Здрасти.

        Мерси за мнението и предложенията.
        В интерес на истината, QNAM използвам на едно единствено място, заедно с WebKit. Това обаче е отделно от това за което ми трябва проверка на връзката с базата. Забравил съм да спомена че базата се намира на отдалечен сървър и идеята е да може да се свързва и тегли информация от нея без значение на какъв интернет се намира клиента и при срив на връзката тя да се възстановява.

        Създаването и отварянето на базата ми се намираха в main, но унифицирах всичко в Common класа, тъй като навсякъде трябваше да повтарям упражнението
        @
        QSqlDatabase db = QSqlDatabase::database("connname");
        QSqlQuery query(db);
        @

        Вярно, не ми съкращава много кода, но според мен с ползването на функцията Common::getDatabase() е по- "чисто".

        За предложението за networkAccessibleChanged намерих "това":http://stackoverflow.com/questions/18365382/how-do-i-get-a-signal-from-qnetworkaccessmanagernetworkaccessiblechanged

        Не ми изглежда да работи коректно, когато има повече от един мрежов интерфейс.... Ще трябва да тествам. Иначе предполагам мога просто с QNAM да проверявам дали въобще имам връзка преди да правя заявки към базата, защото когато програмата стигне до query.exec() просто си забива - таймаута е твърде голям и не намерих начин да го променя :(
        Иначе според теб дали овърхеда за постоянно отваряне и затваряне на връзката към базата ще е проблем? Имам предвид, както писах и в първия пост, да направя отделен клас (или да субкласна QSqlDatabase), от където вече да си изпълнявам заявките на принципа на работа примерно на PHP - без постоянна връзка, когато има заявка - свързва се, изпълнява я, връща резултата и затваря всичко. Дали няма да забавя излишно програмата по тоя начин и да увелича използването на ресурсите? Притеснява ме че QSqlDatabase::close() може и да не затвори връзката ако има все още работещи заявки. Шанс едно на милион, но може да създаде проблеми....

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Robbin
          wrote on 30 Aug 2013, 06:18 last edited by
          #4

          Оказа се че проблема има много просто решение, но човек трябва да седне и да прочете малко документацията /facepalm/

          Ето извадка от документацията:
          @
          void QSqlDatabase::setConnectOptions ( const QString & options = QString() )

          Sets database-specific options. This must be done before the connection is opened or it has no effect (or you can close() the connection, call this function and open() the connection again).
          @

          Към тази функция са описани всички опции които потдържа съответния клиент. За MySQL има MYSQL_OPT_RECONNECT.

          На същото място има дадени примери
          @
          ...
          // MySQL connection
          db.setConnectOptions("CLIENT_SSL=1;CLIENT_IGNORE_SPACE=1"); // use an SSL connection to the server
          if (!db.open()) {
          db.setConnectOptions(); // clears the connect option string
          ...
          }
          ...
          @
          В примера използват option=value синтаксис, но проверих (специално за MySQL) дали става ако само се подадат опциите (без "=1") - всичко е ОК, дори и да се смени доставчика или интернета да е прекъснал за момент, клиента се реконектва и няма проблеми. Ако се загуби връзката, програмата "заспива" и чака MySQL клиента да се реконектне, след което всичко се оправя.

          В моя случай това ще ми свърши работа, надявам се и за други да е полезно ;-)

          1 Reply Last reply
          0
          • R Offline
            R Offline
            Robbin
            wrote on 3 Sept 2013, 15:10 last edited by
            #5

            Всъщност явно "=1" е необходимо, защото след следващата компилация почна да ми хвърля грешки. Така че правилния синтаксис си остава option=value или примерно

            @
            db.setConnectOptions("MYSQL_OPT_RECONNECT=1;CLIENT_SSL=1");
            @

            1 Reply Last reply
            0

            5/5

            3 Sept 2013, 15:10

            • Login

            • Login or register to search.
            5 out of 5
            • First post
              5/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved