2011-09-14 7 views
7

Nasz produkt to procesor transakcji odsłuchowych TCP. Połączenia przychodzące mają przypisany wątek do obsługi połączenia i połączenia DB do pracy.Skuteczny sposób testowania połączenia ODBC

Zamiast kosztownego podejścia do ustanawiania nowego połączenia DB dla każdego przychodzącego połączenia klienta, utrzymujemy pulę połączeń z bazą danych.

Basen połączenia z bazą danych dość konfigurowalne: min/max rozmiary, wskaźniki wzrostu, itp

Niektóre szczegóły:

  • platformy jest Windows 2003/2008 R2
  • DB jest SQL Server 2005/2008 R2
  • Sposób połączenia jest ODBC
  • język programowania C++ jest

Wreszcie pytanie:

Ponieważ usługa może być uruchomiony przez kilka miesięcy bez restartu, istnieje realna szansa, że ​​niektóre z połączeń z bazą danych w puli staną się nieważne. Chcę mieć możliwie najszybszy sposób przetestowania ważności danego połączenia przed przypisaniem go do połączenia przychodzącego.

Obecnie robię to, wykonując prostą instrukcję SQL "SELECT 123;", jednak odkryłem, że ma to znaczny negatywny wpływ na wydajność, gdy używane są plany wykonywania równoległego.

Bardzo krótko w kodzie, co robię jest:

// ... at some point we decide pool needs another connection... 

// Set up database connection 
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); 
SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); 
SQLDriverConnect(conn, 0, in_str, in_len, out_str, DIM(out_str), &out_len, SQL_DRIVER_NOPROMPT); 

// 'conn' is placed in DB connection pool 

// ... some time later a new client connection comes in ... 

// Execute simple statement to test if 'conn' is still OK 
SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); 
SQLExecDirect(stmt, (SQLCHAR*)"SELECT 1;", SQL_NTS); 

// If 'conn' is OK, give it to incoming connection; 
// if not, get another connection from pool 

Cheers,
Dave

+0

Myślę, że jedyną opcją tutaj może być po prostu sprawdzanie połączeń częściej, ale nie tak często, jak za każdym razem. Być może co 5 minut? –

Odpowiedz

7

Dobrze oficjalnym sposobem jest SQLGetConnectAttr (SQL_ATTR_CONNECTION_DEAD), który sprawdza, czy połączenie działa, gdy ostatni próbował.

Lub SQLGetConnectAttr (conn, SQL_COPT_SS_CONNECTION_DEAD, ...), który sprawdza, czy połączenie działa teraz.

+0

To świetnie - odezwę się, gdy odpowiem, gdy to przetestowałem. – user390935

+0

Cześć Nick, Lepszy sposób to: SQLGetConnectAttr (conn, SQL_COPT_SS_CONNECTION_DEAD, ...), ponieważ sprawdza, czy połączenie działa teraz. SQL_ATTR_CONNECTION_DEAD sprawdza tylko, czy połączenie działa podczas ostatniej próby. Dzięki za początkowy wskaźnik - dostałem mnie na właściwą drogę. Pozdrawiam, Dave. – user390935

+1

Myślę, że drugi jest specyficzny dla systemu Windows, ponieważ w unixODBC nie ma takiej definicji i mogę znaleźć tylko "SQL_ATTR_CONNECTION_DEAD". Czy tak powinno być (może nowsza wersja ODBC)? – a1an