fix #29041 - Handle DB reconnect wrt. transactions
authorMiloš Mulač <mulac@civ.zcu.cz>
Tue, 29 Jul 2008 13:15:05 +0000 (13:15 +0000)
committerMiloš Mulač <mulac@civ.zcu.cz>
Tue, 29 Jul 2008 13:15:05 +0000 (13:15 +0000)
- no reconnect number limit

org.glite.lb.common/interface/context.h
org.glite.lb.server/src/db_supp.c
org.glite.lbjp-common.db/src/db.c

index 02fe955..b94a521 100644 (file)
@@ -194,6 +194,7 @@ typedef enum _edg_wll_ErrorCode {
        EDG_WLL_IL_EVENTS_WAITING, /**< Interlogger still has events pending delivery. */
        EDG_WLL_ERROR_COMPARE_EVENTS, /**< Two compared events differ. */
        EDG_WLL_ERROR_DB_TRANS_DEADLOCK,        /**< Deadlock detected during DB operation. */
+       EDG_WLL_ERROR_DB_LOST_CONNECTION,       /**< Lost connection to DB */
 } edg_wll_ErrorCode;
 
 /**
index 050a48b..cf5817e 100644 (file)
@@ -18,6 +18,7 @@ int edg_wll_SetErrorDB(edg_wll_Context ctx) {
        if (ctx->dbctx) {
                code = glite_lbu_DBError(ctx->dbctx, NULL, &ed);
                if (code == EDEADLOCK) code = EDG_WLL_ERROR_DB_TRANS_DEADLOCK;
+               if (code == ERESTART) code = EDG_WLL_ERROR_DB_LOST_CONNECTION;
                edg_wll_SetError(ctx, code, ed);
                free(ed);
        } else {
@@ -95,6 +96,7 @@ int edg_wll_TransNeedRetry(edg_wll_Context ctx) {
        char *errd;
 
        ret = edg_wll_Error(ctx,NULL,NULL);
+
        if (ret == EDG_WLL_ERROR_DB_TRANS_DEADLOCK) {
                if (debug)
                        printf("[%d]: DB deadlock detected. Rolling back transaction and retrying... \n",getpid());
@@ -104,6 +106,18 @@ int edg_wll_TransNeedRetry(edg_wll_Context ctx) {
                edg_wll_Rollback(ctx);
                edg_wll_ResetError(ctx);
                return 1;
+       }
+       if (ret == EDG_WLL_ERROR_DB_LOST_CONNECTION) {
+               if (debug)
+                       printf("[%d]: Lost connection to DB. "
+                               "Rolling back transaction and retrying... \n",getpid());
+               else 
+                       syslog(LOG_INFO,"[%d]: Lost connection to DB. "
+                               "Rolling back transaction and retrying... \n",getpid());
+
+               edg_wll_Rollback(ctx);
+               edg_wll_ResetError(ctx);
+               return 1;
        } else if (ret==0) {
                edg_wll_Commit(ctx); /* errors propagated further */
                return 0;
index 0686f62..033b9f9 100644 (file)
@@ -55,6 +55,7 @@ struct glite_lbu_DBContext_s {
                int code;
                char *desc;
        } err;
+       int in_transaction;     /* this flag is set whenever we are in DB transaction */
 };
 
 
@@ -311,6 +312,7 @@ int glite_lbu_Transaction(glite_lbu_DBContext ctx) {
        if (USE_TRANS(ctx)) {
                if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=0", NULL) < 0) goto err;
                if (glite_lbu_ExecSQL(ctx, "BEGIN", NULL) < 0) goto err;
+               ctx->in_transaction = 1;
        }
 err:
        return STATUS(ctx);
@@ -322,6 +324,7 @@ int glite_lbu_Commit(glite_lbu_DBContext ctx) {
        if (USE_TRANS(ctx)) {
                if (glite_lbu_ExecSQL(ctx, "COMMIT", NULL) < 0) goto err;
                if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err;
+               ctx->in_transaction = 0;
        }
 err:
        return STATUS(ctx);
@@ -333,6 +336,7 @@ int glite_lbu_Rollback(glite_lbu_DBContext ctx) {
        if (USE_TRANS(ctx)) { 
                if (glite_lbu_ExecSQL(ctx, "ROLLBACK", NULL) < 0) goto err;
                if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err;
+               ctx->in_transaction = 0;
        }
 err:
        return STATUS(ctx);
@@ -495,7 +499,11 @@ int glite_lbu_ExecSQL(glite_lbu_DBContext ctx, const char *cmd, glite_lbu_Statem
                                        break;
                                case CR_SERVER_LOST:
                                case CR_SERVER_GONE_ERROR:
-                                       if (retry_nr <= 0) 
+                                       if (ctx->in_transaction) {
+                                               ERR(ctx, ERESTART, db_handle.mysql_error(ctx->mysql));
+                                               return -1;
+                                       }
+                                       else if (retry_nr <= 0) 
                                                do_reconnect = 1;
                                        break;
                                case ER_LOCK_DEADLOCK: