Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8653:4dadcc2f6be2 HEAD
pgsql: More fixes to transaction handling.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 18 Jan 2009 21:02:15 -0500 |
parents | 8b3af54b4dc3 |
children | abb1a50a266d |
files | src/lib-sql/driver-pgsql.c |
diffstat | 1 files changed, 32 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-sql/driver-pgsql.c Sun Jan 18 20:15:26 2009 -0500 +++ b/src/lib-sql/driver-pgsql.c Sun Jan 18 21:02:15 2009 -0500 @@ -79,6 +79,8 @@ 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 @@ 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) { - /* 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); + 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); + } } static int @@ -910,20 +916,21 @@ (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 @@ 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 @@ 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); }