Sascha B
Sascha B

Reputation: 1

SOCI Database Library how to reconnect to Database with ODBC Backend

i am using SOCI Database Lib. I have in my c++ program a timer that checks every x seconds if the connection to the Database still working, using ODBC backend in SOCI. If the program detects that the connection is broken (testquery didn't work), i want to try to reconnect to the Database, this is done by the following workflow:

1.) Try to Create a single connection to the Database and Fire a Select 1 from dual sql statement.
2.) No success do nothing till the next check occurs in the timer.
2.1) If Success i try to reconnect all Sessions to the Database in the connection Pool but this didn't work safe sometimes it works, sometimes it crashes my program, regardless if i try with close() and then open(connstring) or using the reconnect() function on the session. See Code Fragment.

Hope someone can help me how to do/implement a safe way to archive this.

Thx and Regards

Sascha

            try
            {
                // Test with Fresh Connection if Connect successfuly reinit Pool
                soci::session sqlConnForTestFresh;
                sqlConnForTestFresh.open(soci::odbc, "DSN=" + dsn + ";UID=" + username + ";PWD=" + password);
                sqlConnForTestFresh << "select 1 from dual";
                sqlConnForTestFresh.close();

                cout << "Test Successfully Connection there again !" << endl;

                // This will be only executed if no error occoured before
                // now close all Sessions in the Pool
                for (int i = 0; i != EXPORT_API_DATA_DB_POOL_SIZE; i++)
                {
                    soci::session& sql = connPoolOracleDb.at(i);
                    //sql.reconnect(); // <-- This will not work 
                    sql.close(); // <-- Close and then reopen works sometimes
                    sql.open(soci::odbc, "DSN=" + dsn + ";UID=" + username + ";PWD=" + password);
                }

              cout << "Reconnect to Database: Database Connection Pool Successful refreshed" << endl;

            }
            catch (odbc_soci_error const & eo)
            {
                cout << "Reconnect to ExportDatabase : Database Connect Still Failed.");
            }
            catch (exception& ex)
            {
                cout << "Reconnect to ExportDatabase : Database Connect Still Failed.");
            }
        }

Upvotes: 0

Views: 272

Answers (1)

Lucas Ayala
Lucas Ayala

Reputation: 2409

I think that your problem is that at method is not thread-safe. You should access the connection pool using the constructor of session:

soci::session sql(connPoolOracleDb);
sql.reconnect();

Upvotes: 0

Related Questions