Date: Monday, February 13, 2006 @ 15:42:09
Author: gilles
Path: /cvsroot/carob/carob
Modified: include/Connection.hpp (1.55 -> 1.56) src/Connection.cpp (1.62
-> 1.63)
Added calls to reconnect() using 2 macros
Added needed retrieveXXXResult
------------------------+
include/Connection.hpp | 26 ++++-
src/Connection.cpp | 219 ++++++++++++++++++++++-------------------------
2 files changed, 129 insertions(+), 116 deletions(-)
Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.55 carob/include/Connection.hpp:1.56
--- carob/include/Connection.hpp:1.55 Fri Feb 10 09:49:49 2006
+++ carob/include/Connection.hpp Mon Feb 13 15:42:09 2006
@@ -52,8 +52,8 @@
#define RetrieveExecuteUpdateResult 11
#define RetrieveExecuteResult 12
//#define RetrieveExecuteUpdateWithKeysResult 13
-//#define RetrieveCommitResult 14
-//#define RetrieveRollbackResult 15
+#define RetrieveCommitResult 14
+#define RetrieveRollbackResult 15
#define StatementExecute 6
#define Begin 20
#define Commit 21
@@ -496,6 +496,22 @@
BackendException, ProtocolException,
NotImplementedException, UnexpectedException);
/**
+ * Check if the given commit has been successfully performed.
+ *
+ * @return transaction id if the commit has been successfully performed
+ */
+ int64_t retrieveCommitResult() throw (SocketIOException,
+ BackendException, ControllerException,
+ ProtocolException, UnexpectedException);
+ /**
+ * Check if the given rollback has been successfully performed.
+ *
+ * @return the transaction id if the rollback has been successfully performed
+ */
+ int64_t retrieveRollbackResult() throw (SocketIOException,
+ BackendException, ControllerException,
+ ProtocolException, UnexpectedException);
+ /**
* Checks if the given query already executed or not on the controller we are
* currently connected to.
*
@@ -542,9 +558,11 @@
* controller chosen using the policy specified in the connection parameters
* of this connection.
*
- * @throw //TODO
+ * @throw NoMoreControllerException if no valid controller left
+ * @throw DriverException if an other error occured
*/
- void reconnect() throw (NoMoreControllerException, UnexpectedException);
+ void reconnect() throw (NoMoreControllerException,
+ DriverException, UnexpectedException);
/**
* Forbids Connection creation that would lead to unexpected state.
* A connection is either created, ie. connected to a controller or destroyed
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.62 carob/src/Connection.cpp:1.63
--- carob/src/Connection.cpp:1.62 Fri Feb 10 09:54:24 2006
+++ carob/src/Connection.cpp Mon Feb 13 15:42:09 2006
@@ -36,6 +36,32 @@
using namespace CarobNS;
+#define RECONNECT_RETRIES 10
+
+// The reconnection macro:
+// When a SocketIOException occurs between these to macros, sleep and try to
+// reconnect(). Sleeping time depends on the retry #. Only N retries are
+// performed
+#define FO_TRY_NTIMES(N) for (int foCnt=0; foCnt<N; foCnt++) { try {
+#define FO_CATCH_NTIMES break; /* if no exception, get out of the for */\
+} catch (SocketIOException sioe) { ::sleep(static_cast<int>(foCnt*0.5));
reconnect(); } }
+
+/* This gives:
+for (int foCnt=0; foCnt<N; foCnt++)
+{
+ try
+ {
+ ***CODE***
+ break; // if no exception, get out of the for
+ }
+ catch (SocketIOException sioe)
+ {
+ ::sleep(foCnt*0.5); // 0s the 1st and 2nd time, 1s the 3rd and 4th...
+ reconnect();
+ }
+}
+*/
+
Connection::Connection(const ConnectionParameters& prms)
throw (DriverException, ConnectionException, AuthenticationException,
UnexpectedException) :
driverSocketPtr(NULL),
@@ -391,9 +417,11 @@
{
if (mustBeginTransaction)
{
- sendCommand(*driverSocketPtr, Begin);
- transactionId = receiveLongOrException();
- mustBeginTransaction = false;
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
+ sendCommand(*driverSocketPtr, Begin);
+ transactionId = receiveLongOrException();
+ mustBeginTransaction = false;
+ FO_CATCH_NTIMES
}
}
@@ -440,38 +468,20 @@
mustBeginTransaction = true;
}
catch (SocketIOException e)
- {
- //TODO:
- // Connection failed, try to reconnect and re-exec the commit
- //try
- //{
- //reconnect();
-
- //long acknowledgedTransactionId = retrieveCommitResult();
- //if (acknowledgedTransactionId != transactionId)
- //{
- //throw new DriverSQLException(
- //"Protocol error during commit rollback (acknowledge transaction
ID = "
- //+ acknowledgedTransactionId + ", expected transaction ID = "
- //+ transactionId + ")");
- //}
-
- // The controller will automatically redo the commit if it was not done
- // earlier so we can safely return here, this is a success.
- //return;
- //}
- //catch (DriverSQLException e1)
- //{
- // throw new DriverSQLException(
- // "Connection lost during commit of transaction '" + transactionId
- // + "' and automatic reconnect failed", e1);
- //}
- if (isWarningEnabled())
+ { // Connection failed, try to reconnect and re-exec the commit
+ reconnect();
+ int64_t acknowledgedTransactionId = retrieveCommitResult();
+ if (acknowledgedTransactionId != transactionId)
{
- logWarning(fctName, L"I/O Error occured around commit of transaction '"
- + toWString(transactionId) + L"\n" + e.description());
+ throw (DriverException(
+ L"Error during commit failover (acknowledge transaction ID = "
+ + toWString(acknowledgedTransactionId)
+ + L", expected transaction ID = " + toWString(transactionId) +
L")"));
}
- throw;
+
+ // The controller will automatically redo the commit if it was not done
+ // earlier so we can safely return here, this is a success.
+ return;
}
}
@@ -509,13 +519,19 @@
mustBeginTransaction = true;
}
catch (SocketIOException e)
- {
- if (isWarningEnabled())
+ { // Connection failed, try to reconnect and re-exec the rollback
+ reconnect();
+ int64_t acknowledgedTransactionId = retrieveRollbackResult();
+ if (acknowledgedTransactionId != transactionId)
{
- logWarning(fctName, L"I/O Error occured around rollback of transaction '"
- + toWString(transactionId) + L"\n" + e.description());
+ throw (DriverException(
+ L"Error during rollback failover (acknowledge transaction ID = "
+ + toWString(acknowledgedTransactionId)
+ + L", expected transaction ID = " + toWString(transactionId) +
L")"));
}
- throw;
+ // The controller will automatically redo the rollback if it was not
+ // done earlier so we can safely return here, this is a success.
+ return;
}
}
@@ -554,14 +570,18 @@
wstring fctName(L"Connection::PreparedStatementGetMetaData");
LockScope ls(&connectionCS);
-//TODO: try/catch/reconnect
- sendCommand(*driverSocketPtr, PreparedStatementGetMetaData);
- *driverSocketPtr << sqlTemplate;
- if (isDebugEnabled())
- logDebug(fctName, L"Statement sent successfully");
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
+ sendCommand(*driverSocketPtr, PreparedStatementGetMetaData);
+ *driverSocketPtr << sqlTemplate;
+
+ if (isDebugEnabled())
+ logDebug(fctName, L"Statement sent successfully");
+
+ return receiveResultSet();
+ FO_CATCH_NTIMES
- return receiveResultSet();
+ return NULL; //avoid compiler warning
}
void Connection::setConnectionParametersOnRequest(Request &request)
@@ -570,7 +590,6 @@
request.setIsReadOnly(readOnly);
}
-//TODO: check that the code still sticks to java code
DriverResultSet* Connection::statementExecuteQuery
(RequestWithResultSetParameters& request)
throw (SocketIOException, BackendException, ControllerException,
@@ -581,12 +600,12 @@
LockScope ls(&connectionCS);
+ checkIfConnected();
+ beginTransactionIfNeeded();
+
DriverResultSet* retVal = NULL;
- try
- {
- checkIfConnected();
- beginTransactionIfNeeded();
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
setConnectionParametersOnRequest(request);
sendCommand(*driverSocketPtr, StatementExecuteQuery);
@@ -599,20 +618,14 @@
switch(tag)
{
case TT_RESULTSET:
- retVal = new DriverResultSet(this);
+ retVal = new DriverResultSet(this);
break;
//case TT_NULL_RESULTSET: nothing to do, just return NULL
case TT_EXCEPTION:
receiveException();
break;
}
- }
- catch (SocketIOException sioe)
- {
- //TODO: Reconnect and retry
- throw;
- }
-
+ FO_CATCH_NTIMES
return retVal;
}
@@ -624,43 +637,28 @@
LockScope ls(&connectionCS);
+ checkIfConnected();
+ beginTransactionIfNeeded();
+
int controllerResponse = -1;
-
- bool requestIdIsSet = false;
- try
- {
- checkIfConnected();
- beginTransactionIfNeeded();
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
setConnectionParametersOnRequest(request);
sendCommand(*driverSocketPtr, StatementExecuteUpdate);
writeRequestOnStream(request);
request.setId(receiveLongOrException());
- requestIdIsSet = true;
+ FO_CATCH_NTIMES
+ // At this point, the request id has been received, let's retrieve the
+ // update count
+ try
+ {
controllerResponse = static_cast<int>(receiveIntOrException());
}
catch (SocketIOException sioe)
{
- wstring msg = L"Exception while executing write request: "
- + sioe.description()
- + L"). Connection probably lost";
- if (isErrorEnabled())
- logError(fctName, msg);
-
- //TODO:
- //reconnect()
-// if (requestIdIsSet)
-// { // Controller handled the query, check if it was executed
-// int result = retrieveExecuteUpdateResult(request);
-// if (result != -1)
-// return result;
-// }
- // At this point the query failed before any controller succeeded in
- // executing the query
-
- throw SocketIOException(msg);
- //in case exception is not catched
- return -1;
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
+ controllerResponse = retrieveExecuteUpdateResult(request);
+ FO_CATCH_NTIMES
}
return controllerResponse;
@@ -677,10 +675,7 @@
std::list<ResultSetOrUpdateCount> results;
- bool requestIdIsSet = false;
-
- try
- {
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
checkIfConnected();
beginTransactionIfNeeded();
setConnectionParametersOnRequest(request);
@@ -691,34 +686,17 @@
if (isDebugEnabled())
logDebug(fctName, L"Executing Statement.execute(" + (wstring)request +
L")");
request.setId(receiveLongOrException());
- requestIdIsSet = true;
+ FO_CATCH_NTIMES
+ try
+ {
results = fetchMultipleResultsFromStream();
}
catch (SocketIOException sioe)
{
- wstring msg = L"Exception while executing request: "
- + sioe.description()
- + L"). Connection probably lost";
- if (isErrorEnabled())
- logError(fctName, msg);
- //TODO:
-// reconnect();
-// if (requestIdIsSet)
-// { // Controller handled the query, check if it was executed
-// List result = retrieveExecuteResult(request);
-// if (result != null)
-// return result;
-// }
-// // At this point the query failed before any controller succeeded in
-// // executing the query
-//
-// return statementExecute(request);
-
- throw SocketIOException(msg);
- //in case exception is not catched
- return results;
+ FO_TRY_NTIMES(RECONNECT_RETRIES)
+ results = retrieveExecuteResult(request);
+ FO_CATCH_NTIMES
}
-
return results;
}
@@ -896,6 +874,22 @@
return NULL;
}
+int64_t Connection::retrieveCommitResult() throw (SocketIOException,
+ BackendException, ControllerException, ProtocolException,
+ UnexpectedException)
+{
+ sendCommand(*driverSocketPtr, RetrieveCommitResult);
+ return receiveLongOrException();
+}
+
+int64_t Connection::retrieveRollbackResult() throw (SocketIOException,
+ BackendException, ControllerException, ProtocolException,
+ UnexpectedException)
+{
+ sendCommand(*driverSocketPtr, RetrieveRollbackResult);
+ return receiveLongOrException();
+}
+
DriverResultSet* Connection::retrieveExecuteQueryResult(const Request &request)
throw (SocketIOException, BackendException, ControllerException,
ProtocolException, UnexpectedException)
@@ -956,7 +950,8 @@
return results;
}
-void Connection::reconnect() throw (NoMoreControllerException,
UnexpectedException)
+void Connection::reconnect() throw (NoMoreControllerException, DriverException,
+ UnexpectedException)
{
wstring fctName(L"Connection::reconnect");
//Wait until other methods/Commands are done
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits