dovecot-1.2: pgsql: More fixes to transaction handling.

dovecot at dovecot.org dovecot at dovecot.org
Mon Jan 19 04:02:24 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/4dadcc2f6be2
changeset: 8653:4dadcc2f6be2
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jan 18 21:02:15 2009 -0500
description:
pgsql: More fixes to transaction handling.

diffstat:

1 file changed, 32 insertions(+), 21 deletions(-)
src/lib-sql/driver-pgsql.c |   53 ++++++++++++++++++++++++++------------------

diffs (105 lines):

diff -r 8b3af54b4dc3 -r 4dadcc2f6be2 src/lib-sql/driver-pgsql.c
--- 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 @@ 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 s
 
 	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
 		(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
 	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_r
 	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);
 }


More information about the dovecot-cvs mailing list