Mercurial > urweb
diff src/c/urweb.c @ 2000:bddee3af70c4
Tweaking uw_commit() logic, partly to fix a resource clean-up bug on SQL serialization failures
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Tue, 15 Apr 2014 19:12:49 -0400 |
parents | cc7e5d469d1b |
children | 16f5f136a807 |
line wrap: on
line diff
--- a/src/c/urweb.c Mon Feb 24 09:10:31 2014 +0000 +++ b/src/c/urweb.c Tue Apr 15 19:12:49 2014 -0400 @@ -3304,32 +3304,58 @@ } } + if (ctx->transaction_started) { + int code = ctx->app->db_commit(ctx); + + if (code) { + if (ctx->client) + release_client(ctx->client); + + if (code == -1) { + // This case is for a serialization failure, which is not really an "error." + // The transaction will restart, so we should rollback any transactionals + // that triggered above. + + for (i = ctx->used_transactionals-1; i >= 0; --i) + if (ctx->transactionals[i].rollback != NULL) + ctx->transactionals[i].rollback(ctx->transactionals[i].data); + + for (i = ctx->used_transactionals-1; i >= 0; --i) + if (ctx->transactionals[i].free) + ctx->transactionals[i].free(ctx->transactionals[i].data, 1); + + return 1; + } + + for (i = ctx->used_transactionals-1; i >= 0; --i) + if (ctx->transactionals[i].free) + ctx->transactionals[i].free(ctx->transactionals[i].data, 0); + + uw_set_error_message(ctx, "Error running SQL COMMIT"); + return 0; + } + } + for (i = ctx->used_transactionals-1; i >= 0; --i) if (ctx->transactionals[i].rollback == NULL) if (ctx->transactionals[i].commit) { ctx->transactionals[i].commit(ctx->transactionals[i].data); if (uw_has_error(ctx)) { - uw_rollback(ctx, 0); + if (ctx->client) + release_client(ctx->client); + + for (i = ctx->used_transactionals-1; i >= 0; --i) + if (ctx->transactionals[i].rollback != NULL) + ctx->transactionals[i].rollback(ctx->transactionals[i].data); + + for (i = ctx->used_transactionals-1; i >= 0; --i) + if (ctx->transactionals[i].free) + ctx->transactionals[i].free(ctx->transactionals[i].data, 0); + return 0; } } - if (ctx->transaction_started) { - int code = ctx->app->db_commit(ctx); - - if (code) { - if (code == -1) - return 1; - - for (i = ctx->used_transactionals-1; i >= 0; --i) - if (ctx->transactionals[i].free) - ctx->transactionals[i].free(ctx->transactionals[i].data, 0); - - uw_set_error_message(ctx, "Error running SQL COMMIT"); - return 0; - } - } - for (i = 0; i < ctx->used_deltas; ++i) { delta *d = &ctx->deltas[i]; client *c = find_client(d->client);