[open-ils-commits] r17118 - trunk/Open-ILS/src/c-apps (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Fri Aug 6 11:33:13 EDT 2010


Author: scottmk
Date: 2010-08-06 11:33:11 -0400 (Fri, 06 Aug 2010)
New Revision: 17118

Modified:
   trunk/Open-ILS/src/c-apps/oils_sql.c
Log:
Refine the way we detect loss of the database connection.

This is a terrible, horrible, no good, very bad kludge.

We do an innocuous SELECT 1.  If this query succeeds, then we know that the
connection is still good.  If it fails, well...

Sometimes the SELECT 1 query fails, not because the database connection is dead,
but because (due to a previous error) the database is ignoring all commands,
even innocuous SELECTs, until the current transaction is rolled back.  The only
known way to detect this condition via the dbi library is by looking at the error
message returned by dbi_conn_error().  This approach will break if the language
or wording of the message ever changes.

Note: the dbi_conn_ping function purports to determine whether the database
connection is live.  At this writing, it follows the same approach as described
above: try a SELECT 1 and see if it works.  Consequently it presumably suffers
from the same shortcoming: it may erroneously report a dead connection when the
database is in fact just ignoring commands due to a previous error.  In addition,
if it determines (rightly or wrongly) that the connection is dead, it silently
tries to reconnect; if the reconnect is succesful, the function reports that the
connection is still alive, as if nothing had happened.  If you were in the middle
of a transaction at the time, you wouldn't know that it got rolled back.

M    Open-ILS/src/c-apps/oils_sql.c


Modified: trunk/Open-ILS/src/c-apps/oils_sql.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_sql.c	2010-08-06 14:45:31 UTC (rev 17117)
+++ trunk/Open-ILS/src/c-apps/oils_sql.c	2010-08-06 15:33:11 UTC (rev 17118)
@@ -239,13 +239,30 @@
 	@return 1 if the connection is alive, or zero if it isn't.
 */
 int oilsIsDBConnected( dbi_conn handle ) {
+	// Do an innocuous SELECT.  If it succeeds, the database connection is still good.
 	dbi_result result = dbi_conn_query( handle, "SELECT 1;" );
 	if( result ) {
 		dbi_result_free( result );
 		return 1;
 	} else {
-		osrfLogError( OSRF_LOG_MARK, "Database connection isn't working" );
-		return 0;
+		// This is a terrible, horrible, no good, very bad kludge.
+		// Sometimes the SELECT 1 query fails, not because the database connection is dead,
+		// but because (due to a previous error) the database is ignoring all commands,
+		// even innocuous SELECTs, until the current transaction is rolled back.  The only
+		// known way to detect this condition via the dbi library is by looking at the error
+		// message.  This approach will break if the language or wording of the message ever
+		// changes.
+		// Note: the dbi_conn_ping function purports to determine whether the doatabase
+		// connection is live, but at this writing this function is unreliable and useless.
+		static const char* ok_msg = "ERROR:  current transaction is aborted, commands "
+			"ignored until end of transaction block\n";
+		const char* msg;
+		dbi_conn_error( handle, &msg );
+		if( strcmp( msg, ok_msg )) {
+			osrfLogError( OSRF_LOG_MARK, "Database connection isn't working" );
+			return 0;
+		} else
+			return 1;   // ignoring SELECT due to previous error; that's okay
 	}
 }
 



More information about the open-ils-commits mailing list