bool failed:1;
bool committed:1;
+ bool commit_started:1;
};
extern const struct sql_db driver_mysql_db;
return -1;
/* we got disconnected, retry */
return 0;
+ } else if (multi) {
+ ctx->commit_started = TRUE;
}
+
while (_ctx->head != NULL) {
if (transaction_send_query(ctx, _ctx->head->query,
_ctx->head->affected_rows) < 0)
struct mysql_transaction_context *ctx =
(struct mysql_transaction_context *)_ctx;
- if (ctx->failed)
+ if (ctx->failed) {
+ bool rolledback = FALSE;
+ const char *orig_error = t_strdup(ctx->error);
+ if (ctx->commit_started) {
+ /* reset failed flag so ROLLBACK is actually sent.
+ otherwise, transaction_send_query() will return
+ without trying to send the query. */
+ ctx->failed = FALSE;
+ if (transaction_send_query(ctx, "ROLLBACK", NULL) < 0)
+ e_debug(event_create_passthrough(_ctx->event)->
+ add_str("error", ctx->error)->event(),
+ "Rollback failed: %s", ctx->error);
+ else
+ rolledback = TRUE;
+ }
e_debug(sql_transaction_finished_event(_ctx)->
- add_str("error", ctx->error)->event(),
- "Transaction failed: %s", ctx->error);
- else if (ctx->committed)
+ add_str("error", orig_error)->event(),
+ "Transaction failed: %s%s", orig_error,
+ rolledback ? " - Rolled back" : "");
+ } else if (ctx->committed)
e_debug(sql_transaction_finished_event(_ctx)->event(),
"Transaction committed");
else