From f4c0b1874b0533bcf2df1d28d584ff02cfdae3fa Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 18 Jan 2009 21:02:15 -0500 Subject: [PATCH] pgsql: More fixes to transaction handling. --HG-- branch : HEAD --- src/lib-sql/driver-pgsql.c | 51 +++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/lib-sql/driver-pgsql.c b/src/lib-sql/driver-pgsql.c index f63c9ece6c..0360445d4a 100644 --- a/src/lib-sql/driver-pgsql.c +++ b/src/lib-sql/driver-pgsql.c @@ -79,6 +79,8 @@ struct pgsql_transaction_context { const char *error; unsigned int opened:1; + unsigned int begin_succeeded:1; + unsigned int begin_failed:1; unsigned int failed:1; }; @@ -882,24 +884,28 @@ driver_pgsql_transaction_commit(struct sql_transaction_context *_ctx, if (ctx->failed) { callback(ctx->error, context); - if (ctx->opened) + if (!ctx->begin_failed) sql_exec(_ctx->db, "ROLLBACK"); driver_pgsql_transaction_unref(ctx); return; } - if (!ctx->opened) { + ctx->callback = callback; + ctx->context = context; + + if (ctx->first_update != NULL) { + sql_query(_ctx->db, ctx->first_update, + transaction_commit_callback, ctx); + i_free_and_null(ctx->first_update); + } else if (ctx->opened) { + driver_pgsql_query_full(_ctx->db, "COMMIT", + transaction_commit_callback, ctx, + FALSE); + } else { /* nothing done */ ctx->callback(NULL, ctx->context); driver_pgsql_transaction_unref(ctx); - return; } - - ctx->callback = callback; - ctx->context = context; - - driver_pgsql_query_full(_ctx->db, "COMMIT", - transaction_commit_callback, ctx, FALSE); } static int @@ -910,20 +916,21 @@ driver_pgsql_transaction_commit_s(struct sql_transaction_context *_ctx, (struct pgsql_transaction_context *)_ctx; struct sql_result *result; - if (ctx->first_update != NULL) { - ctx->refcount++; - sql_query(_ctx->db, ctx->first_update, - transaction_update_callback, ctx); - i_free_and_null(ctx->first_update); - } - if (ctx->failed) { *error_r = ctx->error; - if (ctx->opened) + if (!ctx->begin_failed) sql_exec(_ctx->db, "ROLLBACK"); - } else if (!ctx->opened) + } else if (ctx->first_update != NULL) { + result = sql_query_s(_ctx->db, ctx->first_update); + if (sql_result_next_row(result) < 0) + *error_r = sql_result_get_error(result); + else + *error_r = NULL; + i_free_and_null(ctx->first_update); + sql_result_free(result); + } else if (!ctx->opened) { *error_r = NULL; - else { + } else { result = sql_query_s(_ctx->db, "COMMIT"); if (ctx->failed) *error_r = ctx->error; @@ -944,7 +951,7 @@ driver_pgsql_transaction_rollback(struct sql_transaction_context *_ctx) struct pgsql_transaction_context *ctx = (struct pgsql_transaction_context *)_ctx; - if (ctx->opened) + if (!ctx->begin_failed) sql_exec(_ctx->db, "ROLLBACK"); driver_pgsql_transaction_unref(ctx); } @@ -955,8 +962,12 @@ transaction_update_callback(struct sql_result *result, void *context) struct pgsql_transaction_context *ctx = context; if (sql_result_next_row(result) < 0) { + if (!ctx->begin_succeeded) + ctx->begin_failed = TRUE; ctx->failed = TRUE; ctx->error = sql_result_get_error(result); + } else { + ctx->begin_succeeded = TRUE; } driver_pgsql_transaction_unref(ctx); } -- 2.47.3