Multithreaded Qt рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ DBMS рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЫрд╛рд▓ рдореЗрдВ рдПрдХ рдмрд╣реБ-рд╕реЗрд╡рд╛ рдкреНрд░рдгрд╛рд▓реА рд▓рд┐рдЦрддреЗ рд╕рдордп, рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЛ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред рдХреНрдпреВрдЯреА рдкрд░ рд╕реЗрд╡рд╛рдПрдВ рд╡рд┐рдХрд╕рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП, рдЙрдиреНрд╣реЛрдВрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП QtSql рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рд╕рдорд╕реНрдпрд╛рдУрдВ


  1. рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ (QSqlDatabase) рд╕реЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдереНрд░реЗрдбреНрд╕ рд╕реЗ рд╕рдорд╛рди рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдПрдХ рд╡рд┐рднрд╛рдЬрди рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИред
  2. рдХреНрдпреЛрдВрдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕рдордп рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдХреА рдПрдХ рд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЦреБрд▓рд╛ рд░рдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдереНрд░реЗрдб рджреНрд╡рд╛рд░рд╛ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ, рдЬрд╛рд░реА рдХрд░рдиреЗ рдФрд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
  3. рдПрдХ рдзрд╛рдЧреЗ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рд▓реЗрдирджреЗрди рдХреЗ рд╕рд╛рде рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдЗрдХрд╛рдИ рдХреНрд░рдо рдореЗрдВ рдЙрддреНрдкрд╛рдж рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЬрдм рдЖрдк рдСрд░реНрдбрд░ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рд╕рднреА рд╕рд╛рдорд╛рди рд╕рд╣реЗрдЬреЗ рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╕рд╛рдорд╛рдиреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╕рдордп рдХреЛрдИ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЖрджреЗрд╢ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реЗ рд▓реЗрдирджреЗрди рдХреЛ рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
  4. рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрдИ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ (рдореИрд╕рдХрд▓, рдкреЛрд╕реНрдЯрдЧреНрд░реИрд╕реАрдХреНрдпреВ)


рдирд┐рд░реНрдгрдп


рдирддреАрдЬрддрди, рд╣рдореЗрдВ 3 рдХрдХреНрд╖рд╛рдПрдВ рдорд┐рд▓реАрдВ:


рд╕рдВрдмрдВрдз

рд╡рд░реНрдЧ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ, QSqlDatabase _conn рд╕рджрд╕реНрдп рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ (рдЦреБрд▓рд╛) рдХрдиреЗрдХреНрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:
Connection::Connection(const QString& ident, const QString& driver, const QString& dbHost, const QString& dbName, const QString& dbUser, const QString& dbPassword, int dbPort) : _threadId(0), _countRef(0), _countBegins(0), _retryCount(0),_invalid(false) { _conn = QSqlDatabase::addDatabase(driver, ident); _conn.setHostName(dbHost); _conn.setDatabaseName(dbName); _conn.setUserName(dbUser); _conn.setPassword(dbPassword); _conn.setPort(dbPort), open(); } 

рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╡рд┐рдзрд┐
  void exec(QSqlQuery& sql); void exec(const char* sql); void exec(const QString& sql); /** *   ,         */ template <typename T> void fetchCol(QSqlQuery& sql,QList<T>& result)... template <typename T> QList<T> fetchCol(QSqlQuery& sql) ... template <typename T> QList<T> fetchCol(const char* sql) ... template <typename T> QList<T> fetchCol(const QString& sql) ... /* *         */ template <typename T> T fetchOne(QSqlQuery& sql, bool* ok = 0) ... template <typename T> T fetchOne(const QString& sql, bool* ok = 0) ... template <typename T> T fetchOne(const char* sql, bool* ok = 0) ... /* *     */ void fetchRow(QSqlQuery& sql,QVariantMap& res); QVariantMap fetchRow(const QString& sql); QVariantMap fetchRow(const char* sql); QVariantMap fetchRow(QSqlQuery& sql); /** *     */ void query(QSqlQuery& sql,QList<QVariant>& result); QList<QVariant> query(const char* sql); QList<QVariant> query(QSqlQuery& sql); QList<QVariant> query(const QString& sql); /*  query */ void fetchAll(QSqlQuery& sql,QList<QVariant>& result); QList<QVariant> fetchAll(const char* sql); QList<QVariant> fetchAll(QSqlQuery& sql); QList<QVariant> fetchAll(const QString& sql); 

рдХреНрдпреЛрдВрдХрд┐ рдХреНрдпреВрдЯреА рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, QSqlQuery рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ QSqlDatabase рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдХреНрд╡реЗрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдЦреНрддреА рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:
  QSqlQuery createQuery() const { return QSqlQuery(_conn);} QSqlQuery createQuery(const QString& sql) { return QSqlQuery(sql, _conn); } 


ManagedConnection

рд╡рд░реНрдЧ рдХрдиреЗрдХреНрд╢рди рдФрд░ ConnetcionManager рдХреЛ рдмрд╛рдВрдзрддрд╛ рд╣реИред
рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп, рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, db1confin) рджреНрд╡рд╛рд░рд╛ ConnetcionManager рд╕реЗ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдПрдХ рдХрдиреЗрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдореЗрдВрдмрд░ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдСрдкрд░реЗрдЯрд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ -> рддрд╛рдХрд┐ рдХрдиреЗрдХреНрд╢рди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПред
рдЖрдорддреМрд░ рдкрд░, рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ "рдбрд┐рдлрд╝реЙрд▓реНрдЯ" рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдерд╛рдЧрдд рдерд╛ред
рдЯрд╛рдЗрдкрдбрд┐рдл рдкреНрд░рдХрд╛рд░ ManagedConnection DConn рдЖрдкрдХреЛ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
 DB::DConn conn; // DB::ManagedConnection conn("default'); //   DB::ManagedConnection c1("db1conn); DB::ManagedConnection c2("db2conn); 


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЫрджреНрдо рдХреЛрдб рдкрд░ рдХреЙрд▓ рд╕реНрдЯреИрдХ рд▓реЗрдВред рдСрд░реНрдбрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рд╕рджрд╕реНрдп рдЖрдЗрдЯрдо рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ (рдЖрдИрдбреАрд▓ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╣реИрдВ)ред рдЖрдЗрдЯрдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдбреЗрдЯрд╛ рд╕рджрд╕реНрдп рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рдбреЗрдЯрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрдкрдирд╛ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, 3 рд╕реНрддрд░реЛрдВ рдкрд░ рдШреЛрдВрд╕рд▓рд╛ рдмрдирд╛рдирд╛:
 Order : save(){ DB::DBConn conn; // . countRef = 1 conn->query('INSERT INTO order...'); item->save(); Item:save() { DB::DBConn conn;// . countRef = 2 conn->query('INSERT INTO item...'); data->save(); Data:save() { DB::DBConn conn;// . countRef = 3 conn->query('INSERT INTO data...'); // ,   ~ManagedConnection countRef = 2 } // ,   ~ManagedConnection countRef = 1 } // ,   ~ManagedConnection countRef = 0 } } } 

ConnectionManager

рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ: рд╣реЛрд╕реНрдЯ, рдкреЛрд░реНрдЯ, рдЖрдзрд╛рд░ рдХрд╛ рдкреНрд░рдХрд╛рд░, рдЖрджрд┐ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ рдкрд╛рд╕ db1 рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рдХрд╛рд░ MySQL рдФрд░ db2 рдкреНрд░рдХрд╛рд░ PostgresSQL рдХреЗ рд╕рд╛рде рдПрдХ рдХрдиреЗрдХреНрд╢рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:
 [database] size = 2 ; 1\ident=db1conn ; ,    MySQL 1\driver=QMYSQL ;  1\host=localhost ;   1\name=db1 ;  1\user=db1_user ; 1\password=lol ; 1\port=3306 ; -         1\max_count = 30 2\ident=db2conn 2\driver=QPSQL 2\host=localhost 2\name=test 2\user=postgres 2\password= 2\port=5432 2\max_count = 30 

рдЬрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ QVariantMap рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЖрд╡реЗрджрди рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЙрджрд╛рд╣рд░рдг
 Application::Application(int& argc, char** argv): QCoreApplication(argc, argv) { ... QVariantMap stgs = settings(); DB::ConnectionManager::init(stgs); ... } 


ConnectionManager рдХреЗ рд╕реНрдерд┐рд░ рд╕рджрд╕реНрдп рдХреЛ рд╡рд┐рдиреНрдпрд╛рд╕ рд╕реЗ рд╕реНрдерд┐рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (static QMap <QString, ConnectionManager *> _instances;)
рдорд╛рдирдЪрд┐рддреНрд░ рдореЗрдВ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╣рдЪрд╛рди рд╡рд┐рдиреНрдпрд╛рд╕ рд╕реЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
 void ConnectionManager::init(const QVariantMap& settings) { const int size = settings.value("database/size").toInt(); for (int i = 1; i <= size; ++i) { const QString ident = settings.value(QString("database/%1/ident").arg(i), "default").toString(); ConnectionManager* inst = new ConnectionManager( ident, settings.value(QString("database/%1/driver").arg(i)).toString(), ... ); _instances[ident] = inst; Log::info(QString("ConnectionManager::init: [%1] [%2@%3:%4] ").arg(inst->_driver).arg(inst->_dbUser).arg(inst->_dbHost).arg(inst->_dbPort)); } } 


рдорд╛рдирдЪрд┐рддреНрд░ рдореЗрдВ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╣рдЪрд╛рди рд╡рд┐рдиреНрдпрд╛рд╕ рд╕реЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
GetConnection class рдХрд╛ рдореБрдЦреНрдп рддрд░реАрдХрд╛ (рдХреЛрдб рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ):

 Connection* ConnectionManager::getConnection() { Connection* conn = 0; int count = 0; while(count++ < MAX_RETRY_GET_CONN_COUNT) { pthread_t thread_id = pthread_self(); //  ,           { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); //    if (conn && conn->threadID() == thread_id && conn->isValid()) { //         conn->lock(); //Log::debug(QString("ConnectionManager::getConnection          thread [%1])").arg(conn->name())); return conn; } } } //       ,       { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (conn && !conn->isLocked() && conn->isValid() ) { //Log::debug(QString("ConnectionManager::getConnection    [%1])").arg(conn->name())); //   conn->lock(); return conn; } } } //       { QMutexLocker mlocker(&_mutex); if(_currentCount < _maxCount) { //      //    //try { conn = new Connection( QString("%1_%2").arg(_ident).arg(_currentCount), _driver, _dbHost, _dbName, _dbUser, _dbPassword,_dbPort ); _currentCount++; conn->lock(); _pool.append(conn); return conn; /*} catch(exc::Message& ex) { delete conn; throw ex; }*/ } else { //   //Log::warn("  - [%d]    DB  [%d]",_maxCount,count); /*for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (!conn->isValid() && !conn->isLocked() ) { removeConnection(conn); break; } }*/ } } // , //     sleep(2); } Log::crit(" %d       ",MAX_RETRY_GET_CONN_COUNT); { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (!conn->isValid() && !conn->isLocked()) { removeConnection(conn); break; } } } throw exc::Message("     "); //return 0; } 

рдХрд╛рдо рдХрд╛ рддрд░реНрдХ


рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╣реИ, рдФрд░ рдЙрдирдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдХреНрдпрд╛ рд╣реИ, рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдЯреЗрдХреНрд╕реНрдЯрдореИрдиреЗрдЬрд░ рдХреЛ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЬрдм рдЖрдк DB :: ManagedConnection рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк ConnetctionManager рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ ConnetctionManager рд╕реЗ рдПрдХ рд╕рдВрдХреЗрддрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ :: getConnetctionред
ConnetctionManager рдореЗрдВ :: рдХрдИ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ getConnetction рд╣реЛрддрд╛ рд╣реИ:
  1. рдбреНрд░рд╛рдЗрд╡ рд╕реЗ рдПрдХ рдХрдиреЗрдХреНрд╢рди рд▓реЗрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдЬрд┐рд╕рдХрд╛ рдереНрд░реЗрдб_рдб рд╡рд░реНрддрдорд╛рди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд░рд┐рдлрдВрдб рдХреЛ 1 рд╕реЗ рдмрдврд╝рд╛рдХрд░ рд╡рд╛рдкрд╕ рдХрд░реЗрдВ
  2. рдбреНрд░рд╛рдЗрд╡ рд╕реЗ рдореБрдлреНрдд рдХрдиреЗрдХреНрд╢рди рд▓реЗрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдпрджрд┐ рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рд╡рд╛рдкрд╕ рд▓реМрдЯреЗрдВ, рдХрдиреЗрдХреНрд╢рди 1 рд╕реЗ рдмрдврд╝рд╛рдПрдВ
  3. рдпрджрд┐ рд╕рднреА рдХрдиреЗрдХреНрд╢рди рд╡реНрдпрд╕реНрдд рд╣реИрдВ рдФрд░ рдЕрдзрд┐рдХрддрдо рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗ рд╣реИрдВред рд╕реАрдорд╛, рдлрд┐рд░ рдПрдХ рдирдпрд╛ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдПрдВ, рдЗрд╕реЗ рдкреВрд▓ рдореЗрдВ рдбрд╛рд▓реЗрдВ рдФрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯреЗрдВ

DB :: ManagedConnection рд╡рд░реНрдЧ рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдХрдиреЗрдХреНрд╢рди RefCount рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ refCount == 0, рдХрдиреЗрдХреНрд╢рди рдЕрдиреНрдп рдереНрд░реЗрдбреНрд╕ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ



 QList<QVariant> Bank::banksByAccountNumber(const QString& accountNumber) { QList<QVariant> res; DB::ManagedConnection conn; foreach(const QVariant& row, conn->fetchAll( "SELECT `real` as state ,namen as name,namep as full_name," "newnum as bik,ksnp as korr_acc,okpo as okpo,nnp as city," "ind as zip, adr as address,regn as regnum, telef as phones FROM `bankdinfo` WHERE `real` = '' ORDER BY RAND()" )) { if(isBelongToBank((row.toMap()["bik"]).toString(),accountNumber)) { res.append(row); } } Log::debug("Banks found %d",res.size()); return res; } 


рдЧреАрдереВрдм рдкрд░ рд╕реВрддреНрд░
рдпреБрдкреАрдбреА
рд▓реЛрдб рдХреЗ рдЪрд░рдо рдкрд░, рдХрдиреЗрдХреНрд╢рди рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ (рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ) рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рд▓реЛрдб рдбреНрд░реЙрдк рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдХрдиреЗрдХреНрд╢рди рдмрдВрдж рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрд╕рд╛рдзрди рдирд╣реАрдВ рд▓реЗрддреЗ рд╣реИрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдПрдХ рдзрд╛рдЧреЗ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬреЛ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛, рдЙрдирдХреА рдЗрд╖реНрдЯрддрдо рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдВрдЦреНрдпрд╛ рдЗрд╕ рд╕рдордп рдХреНрдпрд╛ рдорд╛рдкрджрдВрдб рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧреАред
рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди, рд╣рдореЗрдВ рдЗрд╕ рддрдереНрдп рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдХрд┐ MySQL рджрд┐рди рдореЗрдВ рдПрдХ рдмрд╛рд░ рдХрдиреЗрдХреНрд╢рди рдХрд╛рдЯрддрд╛ рд╣реИ, рдФрд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ DBMS рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдкреНрд▓реАрдХреЗрд╢рди рдлреЙрд▓реНрдЯ рдЯреЙрд▓рд░реЗрдВрд╕ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдХрдиреЗрдХреНрд╢рди рдореЗрдВ рдмрд╣реБрдд рд▓рдЪреАрд▓рд╛ рдХреЛрдб рдирд╣реАрдВ рдЬреЛрдбрд╝рдирд╛ рдкрдбрд╝рд╛:
 bool Connection::tryRetry(const QSqlError& err) { //    bool needRecon = false; QRegExp mrx("MySQL server has gone away"); if (err.type() == QSqlError::NoError && qstrcmp(_conn.driver()->handle().typeName(), "PGconn*") == 0) { needRecon = true; } else if ( /*(qstrcmp(_conn.driver()->handle().typeName(), "MYSQL*") == 0)*/ err.text().contains(mrx)) { needRecon = true; } bool ok = false; if (needRecon) { Log::err( "     - GONE AWAY.   ..."); bool lol = true; while(lol) { if (_retryCount >= MAX_RETRY_COUNT) { _retryCount = 0; _invalid = true; Log::crit( "       ."); throw exc::Message("     "); } lol = !reconnect(); if(!lol) { ok = true; _retryCount = 0; break; } _retryCount++; sleep(2); } } //_retryCount return ok; } void Connection::query(QSqlQuery& sql, QList<QVariant>& result) { if (!sql.exec()) { if (tryRetry(sql.lastError())) { if(isValid()) { QSqlQuery qs = createQuery(); cpQuery(sql, qs); Log::warn("   ..."); return query(qs, result); } else { throw exc::Message("    ");; } } else throw exc::Sql(sql); } ... } 

Source: https://habr.com/ru/post/In164377/


All Articles