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,
#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
{
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"
#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;
struct timeval to;
int request_timeout = REQUEST_TIMEOUT;
int silent = 0;
- int transactions = 0;
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;
/* 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))
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) )
{
/* 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;
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){
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;
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;
/* 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;
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);
}