From 6429801d8c192bf9e8c63fdfd72b3e9c900b089e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Fri, 30 Jun 2006 13:06:26 +0000 Subject: [PATCH] Implemented transaction support test. Using transactions can be forced by -b option. --- org.glite.lb.server/interface/lbs_db.h | 2 +- org.glite.lb.server/src/bkserverd.c | 22 ++++-- org.glite.lb.server/src/lbs_db.c | 103 ++++++++++++++++++------- org.glite.lb.server/test/test_query_events.cpp | 2 +- 4 files changed, 94 insertions(+), 35 deletions(-) diff --git a/org.glite.lb.server/interface/lbs_db.h b/org.glite.lb.server/interface/lbs_db.h index df557c0..8febdf0 100644 --- a/org.glite.lb.server/interface/lbs_db.h +++ b/org.glite.lb.server/interface/lbs_db.h @@ -20,7 +20,7 @@ typedef struct _edg_wll_Stmt *edg_wll_Stmt; edg_wll_ErrorCode edg_wll_DBConnect( edg_wll_Context, /* INOUT: */ - char * /* IN: connect string user/password@host:database */ + const char * /* IN: connect string user/password@host:database */ ); diff --git a/org.glite.lb.server/src/bkserverd.c b/org.glite.lb.server/src/bkserverd.c index 7567f5f..24f5929 100644 --- a/org.glite.lb.server/src/bkserverd.c +++ b/org.glite.lb.server/src/bkserverd.c @@ -120,6 +120,7 @@ static int hardJobsLimit = 0; static int hardEventsLimit = 0; static int hardRespSizeLimit = 0; static char *dbstring = NULL,*fake_host = NULL; +int transactions = -1; static int fake_port = 0; static char **super_users = NULL; static int slaves = 10, @@ -177,11 +178,11 @@ static struct option opts[] = { #ifdef LB_PERF {"perf-sink", 1, NULL, 'K'}, #endif - {"transactions", 0, NULL, 'b'}, + {"transactions", 1, NULL, 'b'}, {NULL,0,NULL,0} }; -static const char *get_opt_string = "a:c:k:C:V:p:drm:ns:l:L:N:i:S:D:X:Y:T:t:J:jzb" +static const char *get_opt_string = "a:c:k:C:V:p:drm:ns:l:L:N:i:S:D:X:Y:T:t:J:jzb:" #ifdef GLITE_LB_SERVER_WITH_WS "w:" #endif @@ -194,7 +195,7 @@ static void usage(char *me) { fprintf(stderr,"usage: %s [option]\n" "\t-a, --address\t use this server address (may be faked for debugging)\n" - "\t-b, --transactions\t use transactions\n" + "\t-b, --transactions\t transactions switch\n" "\t-k, --key\t private key file\n" "\t-c, --cert\t certificate file\n" "\t-C, --CAdir\t trusted certificates directory\n" @@ -285,6 +286,7 @@ struct clnt_data_t { #ifdef GLITE_LB_SERVER_WITH_WS struct soap *soap; #endif /* GLITE_LB_SERVER_WITH_WS */ + int use_transactions; void *mysql; edg_wll_QueryRec **job_index; edg_wll_IColumnRec *job_index_cols; @@ -312,7 +314,6 @@ int main(int argc, char *argv[]) struct timeval to; int request_timeout = REQUEST_TIMEOUT; int silent = 0; - int transactions = 0; @@ -336,7 +337,7 @@ int main(int argc, char *argv[]) while ((opt = getopt_long(argc,argv,get_opt_string,opts,NULL)) != EOF) switch (opt) { case 'a': fake_host = strdup(optarg); break; - case 'b': transactions = 1; break; + case 'b': transactions = atoi(optarg); break; case 'c': server_cert = optarg; break; case 'k': server_key = optarg; break; case 'C': cadir = optarg; break; @@ -564,7 +565,6 @@ a.sin_addr.s_addr = INADDR_ANY; /* Just check the database and let it be. The slaves do the job. */ edg_wll_InitContext(&ctx); - ctx->use_transactions = transactions; wait_for_open(ctx, dbstring); if (edg_wll_DBCheckVersion(ctx)) @@ -645,6 +645,7 @@ int bk_clnt_data_init(void **data) if ( !dbstring ) dbstring = getenv("LBDB"); wait_for_open(ctx, dbstring); cdata->mysql = ctx->mysql; + cdata->use_transactions = ctx->use_transactions; if ( edg_wll_QueryJobIndices(ctx, &job_index, NULL) ) { @@ -753,6 +754,7 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data) /* Shared structures (pointers) */ ctx->mysql = cdata->mysql; + ctx->use_transactions = cdata->use_transactions; ctx->job_index_cols = cdata->job_index_cols; ctx->job_index = cdata->job_index; @@ -1261,6 +1263,14 @@ static void wait_for_open(edg_wll_Context ctx, const char *dbstring) dprintf(("[%d]: DB connection established\n",getpid())); if (!debug) syslog(LOG_INFO,"DB connection established\n"); } + + if (!ctx->use_transactions && transactions != 0) { + fprintf(stderr, "[%d]: transaction aren't supported!\n", getpid()); + } + if (transactions >= 0) { + ctx->use_transactions = transactions; + fprintf(stderr, "[%d]: transactions forced from %d to %d\n", getpid(), ctx->use_transactions, transactions); + } } static void free_hostent(struct hostent *h){ diff --git a/org.glite.lb.server/src/lbs_db.c b/org.glite.lb.server/src/lbs_db.c index 6a28fa7..9f169ba 100644 --- a/org.glite.lb.server/src/lbs_db.c +++ b/org.glite.lb.server/src/lbs_db.c @@ -27,7 +27,8 @@ struct _edg_wll_Stmt { edg_wll_Context ctx; }; -edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx,char *cs) + +static edg_wll_ErrorCode db_connect(edg_wll_Context ctx, const char *cs, MYSQL **mysql) { char *buf = NULL; char *host,*user,*pw,*db; @@ -35,10 +36,10 @@ edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx,char *cs) if (!cs) cs = DEFAULTCS; - if (!(ctx->mysql = (void *) mysql_init(NULL))) + if (!(*mysql = mysql_init(NULL))) return edg_wll_SetError(ctx,ENOMEM,NULL); - mysql_options(ctx->mysql, MYSQL_READ_DEFAULT_FILE, "my"); + mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my"); host = user = pw = db = NULL; @@ -61,24 +62,81 @@ edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx,char *cs) /* ljocha: CLIENT_FOUND_ROWS added to make authorization check * working in update_notif(). * Hope it does not break anything else */ - if (!mysql_real_connect((MYSQL *) ctx->mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { + if (!mysql_real_connect(*mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { free(buf); return my_err(); } free(buf); + return edg_wll_ResetError(ctx); +} + + +static void db_close(MYSQL *mysql) { + mysql_close(mysql); +} + + +static int transaction_test(edg_wll_Context ctx, MYSQL *m2) { + MYSQL *m1; + char *desc; + int retval; + edg_wll_ErrorCode err; + + ctx->use_transactions = 1; + + m1 = (MYSQL *)ctx->mysql; + edg_wll_ExecStmt(ctx, "drop table test", NULL); + if (edg_wll_ExecStmt(ctx, "create table test (item int)", NULL) != 0) goto err1; + if (edg_wll_Transaction(ctx) != 0) goto err2; + if (edg_wll_ExecStmt(ctx, "insert into test (item) values (1)", NULL) != 1) goto err2; + + ctx->mysql = (void *)m2; + if ((retval = edg_wll_ExecStmt(ctx, "select item from test", NULL)) == -1) goto err2; + ctx->use_transactions = (retval == 0); + + ctx->mysql = (void *)m1; + if (edg_wll_Commit(ctx) != 0) goto err2; + if (edg_wll_ExecStmt(ctx, "drop table test", NULL) != 0) goto err1; + #ifdef LBS_DB_PROFILE fprintf(stderr, "[%d] use_transactions = %d\n", getpid(), ctx->use_transactions); #endif - return edg_wll_ResetError(ctx); + + return 0; +err2: + edg_wll_Error(ctx, &err, &desc); + edg_wll_ExecStmt(ctx, "drop table test", NULL); + edg_wll_SetError(ctx, err, desc); +err1: + return edg_wll_Error(ctx, NULL, NULL); } + +edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx, const char *cs) +{ + MYSQL *m2; + int errcode; + + if ((errcode = db_connect(ctx, cs, (MYSQL **)&ctx->mysql)) == 0) { + if ((errcode = db_connect(ctx, cs, (MYSQL **)&m2)) == 0) { + errcode = transaction_test(ctx, m2); + db_close(m2); + } + if (errcode) edg_wll_DBClose(ctx); + } + + return errcode; +} + + void edg_wll_DBClose(edg_wll_Context ctx) { - mysql_close((MYSQL *) ctx->mysql); + db_close((MYSQL *) ctx->mysql); ctx->mysql = NULL; } + int edg_wll_ExecStmt(edg_wll_Context ctx,char *txt,edg_wll_Stmt *stmt) { int err; @@ -233,41 +291,32 @@ int edg_wll_DBCheckVersion(edg_wll_Context ctx) int edg_wll_Transaction(edg_wll_Context ctx) { - int err = 0; - if (ctx->use_transactions) { - err = edg_wll_ExecStmt(ctx, "set autocommit=0", NULL); - if (!err) - return edg_wll_ExecStmt(ctx, "begin", NULL); + if (edg_wll_ExecStmt(ctx, "set autocommit=0", NULL) < 0) goto err; + if (edg_wll_ExecStmt(ctx, "begin", NULL) < 0) goto err; } - - return err; +err: + return edg_wll_Error(ctx, NULL, NULL); } int edg_wll_Commit(edg_wll_Context ctx) { - int err = 0; - if (ctx->use_transactions) { - err = edg_wll_ExecStmt(ctx, "commit", NULL); - if (!err) - return edg_wll_ExecStmt(ctx, "set autocommit=1", NULL); + if (edg_wll_ExecStmt(ctx, "commit", NULL) < 0) goto err; + if (edg_wll_ExecStmt(ctx, "set autocommit=1", NULL) < 0) goto err; } - - return err; +err: + return edg_wll_Error(ctx, NULL, NULL); } int edg_wll_Rollback(edg_wll_Context ctx) { - int err = 0; - if (ctx->use_transactions) { - err = edg_wll_ExecStmt(ctx, "rollback", NULL); - if (!err) - return edg_wll_ExecStmt(ctx, "set autocommit=1", NULL); + if (edg_wll_ExecStmt(ctx, "rollback", NULL) < 0) goto err; + if (edg_wll_ExecStmt(ctx, "set autocommit=1", NULL) < 0) goto err; } - - return err; +err: + return edg_wll_Error(ctx, NULL, NULL); } diff --git a/org.glite.lb.server/test/test_query_events.cpp b/org.glite.lb.server/test/test_query_events.cpp index 8234f99..cda12eb 100644 --- a/org.glite.lb.server/test/test_query_events.cpp +++ b/org.glite.lb.server/test/test_query_events.cpp @@ -131,7 +131,7 @@ int edg_wll_QueryColumns(edg_wll_Stmt stmt, char**cols) { return 0; } char *edg_wll_TimeToDB(long t) { return NULL; } time_t edg_wll_DBToTime(char *c) { return (time_t)-1; } -edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx, char*str) { +edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx, const char*str) { return (edg_wll_ErrorCode)0; } -- 1.8.2.3