static void print_blob(unsigned long len, char *blob) {
-       int i;
+       unsigned int i;
+
        for (i = 0; i < len; i++) printf("%02X ", blob[i]);
        printf("(='");
        for (i = 0; i < len; i++) printf("%c", blob[i]);
        dprintf(("prepare-insert...\n"));
        if (glite_lbu_PrepareStmt(ctx, INSERT_CMD, &stmt) != 0) goto failcon;
        dprintf(("execute 1. insert...\n"));
-       if (glite_lbu_ExecStmt(stmt, 3,
+       if (glite_lbu_ExecPreparedStmt(stmt, 3,
                               GLITE_LBU_DB_TYPE_INT, 2,
                               GLITE_LBU_DB_TYPE_VARCHAR, "cicomexocitl.civ",
                               GLITE_LBU_DB_TYPE_BLOB, blob1, sizeof(blob1) - 1) != 1) goto failstmt;
        dprintf(("execute 2. insert...\n"));
-       if (glite_lbu_ExecStmt(stmt, 3,
+       if (glite_lbu_ExecPreparedStmt(stmt, 3,
                               GLITE_LBU_DB_TYPE_INT, 3,
                               GLITE_LBU_DB_TYPE_VARCHAR, "tartarus",
                               GLITE_LBU_DB_TYPE_NULL) != 1) goto failstmt;
        dprintf(("execute 3. insert...\n"));
-       if (glite_lbu_ExecStmt(stmt, 3,
+       if (glite_lbu_ExecPreparedStmt(stmt, 3,
                               GLITE_LBU_DB_TYPE_INT, 4,
                               GLITE_LBU_DB_TYPE_VARCHAR, "harpia",
                               GLITE_LBU_DB_TYPE_BLOB, blob2, sizeof(blob2)) != 1) goto failstmt;
 
        user = "cicomexocitl.civ";
        dprintf(("executing '%s'...\n", user));
-       if (glite_lbu_ExecStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt;
+       if (glite_lbu_ExecPreparedStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt;
        dprintf(("fetching '%s'...\n", user));
        while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) {
                dprintf(("Result: n=%d, res=%p\n", nr, res));
 
 struct glite_lbu_DBContext_s {
        MYSQL *mysql;
        const char *cs;
-       int have_caps;
        int caps;
        struct {
                int code;
 static int myisokstmt(glite_lbu_Statement stmt, const char *source, int line, int *retry);
 static int db_connect(glite_lbu_DBContext ctx, const char *cs, MYSQL **mysql);
 static void db_close(MYSQL *mysql);
-static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions);
+static int transaction_test(glite_lbu_DBContext ctx);
 static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results);
 static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
 void set_time(MYSQL_TIME *mtime, const time_t time);
 
 int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx) {
        MYSQL   *m = ctx->mysql;
-       MYSQL   *m2;
-       int     major,minor,sub,version,caps,have_transactions=0;
+       int     major,minor,sub,version,caps,origcaps;
        const char *ver_s;
 
-       if (ctx->have_caps) return ctx->caps;
-
+       origcaps = ctx->caps;
        caps = 0;
 
        ver_s = mysql_get_server_info(m);
        if (version >= GLITE_LBU_MYSQL_PREPARED_VERSION) caps |= GLITE_LBU_DB_CAP_PREPARED;
 
        CLR_ERR(ctx);
+       transaction_test(ctx);
+       if ((ctx->caps & GLITE_LBU_DB_CAP_TRANSACTIONS)) caps |= GLITE_LBU_DB_CAP_TRANSACTIONS;
 
-       if (db_connect(ctx, ctx->cs, &m2) == 0) {
-               transaction_test(ctx, m2, &have_transactions);
-               db_close(m2);
-       }
-       if (have_transactions) caps |= GLITE_LBU_DB_CAP_TRANSACTIONS;
-
-       if (STATUS(ctx) == 0) {
-               ctx->have_caps = 1;
-               return caps;
-       } else return -1;
+       ctx->caps = origcaps;
+       if (STATUS(ctx) == 0) return caps;
+       else return -1;
 }
 
 
                return STATUS(ctx);
 
        while ((ret = glite_lbu_FetchRow(stmt,sizeof(showcol)/sizeof(showcol[0]),NULL,showcol)) > 0) {
-               assert(ret <= sizeof showcol/sizeof showcol[0]);
+               assert(ret <= (int)(sizeof showcol/sizeof showcol[0]));
 
                if (!col_names) {
                        col_names = malloc(ret * sizeof col_names[0]);
                                        return -1;
                                        break;
                                case CR_SERVER_LOST:
+                               case CR_SERVER_GONE_ERROR:
                                        if (retry_nr <= 0) 
                                                do_reconnect = 1;
                                        break;
 }
 
 
-int glite_lbu_ExecStmt(glite_lbu_Statement stmt, int n, ...) {
+int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) {
        int i;
        va_list ap;
        glite_lbu_DBType type;
 }
 
 
-int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, void *mysql, const char *table_name, long size_limit, long record_limit, const char *columns)
+int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, const char *table_name, long size_limit, long record_limit, const char *columns)
 {
        *bi = calloc(1, sizeof(*bi));
        (*bi)->ctx = ctx;
                        return -1;
                        break;
                case CR_SERVER_LOST:
+               case CR_SERVER_GONE_ERROR:
                        if (*retry > 0) {
                                (*retry)--;
                                return 0;
        char    *host,*user,*pw,*db; 
        char    *slash,*at,*colon;
        int      ret;
+#ifdef MYSQL_OPT_RECONNECT
+       my_bool reconnect = 1;
+#endif
 
        // needed for SQL result parameters
        assert(sizeof(int) >= sizeof(my_bool));
        if (!(*mysql = mysql_init(NULL))) return ERR(ctx, ENOMEM, NULL);
 
        mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my");
+#ifdef MYSQL_OPT_RECONNECT
+       /* XXX: may result in weird behaviour in the middle of transaction */
+       mysql_options(*mysql, MYSQL_OPT_RECONNECT, &reconnect);
+#endif
 
        host = user = pw = db = NULL;
 
 
 /*
  * test transactions capability:
- *
- * 1) with connection 1 create testing table test<pid>
- * 2) with connection 1 insert a value
- * 3) with connection 2 look for a value, transactions are for no error and
- *    no items found
- * 4) with connection 1 commit and drop  the table
  */
-static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions) {
-       MYSQL *m1;
-       char *desc, *cmd_create, *cmd_insert, *cmd_select, *cmd_drop;
+static int transaction_test(glite_lbu_DBContext ctx) {
+       glite_lbu_Statement stmt;
+       char *table[1] = { NULL }, *res[2] = { NULL, NULL }, *cmd = NULL;
        int retval;
-       int err;
-       pid_t pid;
 
-       ctx->caps |= GLITE_LBU_DB_CAP_TRANSACTIONS;
-       pid = getpid();
-       *have_transactions = 0;
+       ctx->caps &= ~GLITE_LBU_DB_CAP_TRANSACTIONS;
 
-       asprintf(&cmd_create, "CREATE TABLE test%d (item INT) ENGINE='innodb'", pid);
-       asprintf(&cmd_insert, "INSERT INTO test%d (item) VALUES (1)", pid);
-       asprintf(&cmd_select, "SELECT item FROM test%d", pid);
-       asprintf(&cmd_drop, "DROP TABLE test%d", pid);
-
-       m1 = ctx->mysql;
-       //glite_lbu_ExecSQL(ctx, cmd_drop, NULL);
-       if (glite_lbu_ExecSQL(ctx, cmd_create, NULL) != 0) goto err1;
-       if (glite_lbu_Transaction(ctx) != 0) goto err2;
-       if (glite_lbu_ExecSQL(ctx, cmd_insert, NULL) != 1) goto err2;
-
-       ctx->mysql = m2;
-       if ((retval = glite_lbu_ExecSQL(ctx, cmd_select, NULL)) == -1) goto err2;
+       if ((retval = glite_lbu_ExecSQL(ctx, "SHOW TABLES", &stmt)) <= 0 || glite_lbu_FetchRow(stmt, 1, NULL, table) < 0) goto quit;
+       glite_lbu_FreeStmt(&stmt);
 
-       ctx->mysql = m1;
-       if (glite_lbu_Commit(ctx) != 0) goto err2;
-       if (glite_lbu_ExecSQL(ctx, cmd_drop, NULL) != 0) goto err1;
+       trio_asprintf(&cmd, "SHOW CREATE TABLE %|Ss", table[0]);
+       if (glite_lbu_ExecSQL(ctx, cmd, &stmt) <= 0 || (retval = glite_lbu_FetchRow(stmt, 2, NULL, res)) < 0 ) goto quit;
+       if (retval != 2 || strcmp(res[0], table[0])) ERR(ctx, EIO, "unexpected show create result");
+       else ctx->caps |= GLITE_LBU_DB_CAP_TRANSACTIONS;
 
 #ifdef LBS_DB_PROFILE
        fprintf(stderr, "[%d] use_transactions = %d\n", getpid(), USE_TRANS(ctx));
 #endif
 
-       *have_transactions = retval == 0;
-       goto ok;
-err2:
-       err = ctx->err.code;
-       desc = ctx->err.desc;
-       glite_lbu_ExecSQL(ctx, cmd_drop, NULL);
-       ctx->err.code = err;
-       ctx->err.desc = desc;
-err1:
-ok:
-       free(cmd_create);
-       free(cmd_insert);
-       free(cmd_select);
-       free(cmd_drop);
+quit:
+       glite_lbu_FreeStmt(&stmt);
+       if (table[0]) free(table[0]);
+       if (res[0]) free(res[0]);
+       if (res[1]) free(res[1]);
+       if (cmd) free(cmd);
        return STATUS(ctx);
 }
 
  */
 static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results) {
        MYSQL_ROW            row;
-       int                  nr, i;
+       unsigned int         nr, i;
        unsigned long       *len;
 
        CLR_ERR(ctx);
  * prepared version of the fetch
  */
 static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) {
-       int ret, retry, i;
+       int ret, retry;
+       unsigned int i;
        MYSQL_BIND *binds = NULL;
        unsigned long *lens = NULL;