From ad612623be5facd4e89fcc9347217d6c7ab1778b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 5 Jul 2022 12:13:58 +0200 Subject: -run read-only transactions in proper read-only scope (at least some of them) --- src/exchange/taler-exchange-httpd_common_deposit.c | 2 +- src/exchange/taler-exchange-httpd_responses.c | 10 +++--- src/exchangedb/plugin_exchangedb_postgres.c | 40 ++++++++++++++++++++++ src/include/taler_exchangedb_plugin.h | 12 +++++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_common_deposit.c b/src/exchange/taler-exchange-httpd_common_deposit.c index 92e2469f2..84d9448aa 100644 --- a/src/exchange/taler-exchange-httpd_common_deposit.c +++ b/src/exchange/taler-exchange-httpd_common_deposit.c @@ -240,7 +240,7 @@ TEH_common_deposit_check_purse_deposit ( GNUNET_break_op (0); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, - /* FIXME: other error code? */ + /* FIXME-Oec: other error code? */ TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_AGE_ATTESTATION_FAILURE, "invalid attest for minimum age"); } diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index bcdc14ece..2642f433a 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -568,10 +568,9 @@ TEH_RESPONSE_reply_coin_insufficient_funds ( json_t *history; TEH_plugin->rollback (TEH_plugin->cls); - // FIXME: maybe start read-only transaction here? if (GNUNET_OK != - TEH_plugin->start_read_committed (TEH_plugin->cls, - "get_coin_transactions")) + TEH_plugin->start_read_only (TEH_plugin->cls, + "get_coin_transactions")) { return TALER_MHD_reply_with_error ( connection, @@ -900,10 +899,9 @@ TEH_RESPONSE_reply_reserve_insufficient_balance ( enum GNUNET_DB_QueryStatus qs; MHD_RESULT mhd_ret; - // FIXME: maybe start read-committed here? if (GNUNET_OK != - TEH_plugin->start (TEH_plugin->cls, - "get_reserve_history on insufficient balance")) + TEH_plugin->start_read_only (TEH_plugin->cls, + "get_reserve_history on insufficient balance")) { GNUNET_break (0); return TALER_MHD_reply_with_error (connection, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index b7a0e8198..53be0364c 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -4450,6 +4450,45 @@ postgres_start_read_committed (void *cls, } +/** + * Start a READ ONLY serializable transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging) + * must point to a constant + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +postgres_start_read_only (void *cls, + const char *name) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ( + "START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + GNUNET_assert (NULL != name); + if (GNUNET_SYSERR == + postgres_preflight (pg)) + return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting READ ONLY transaction `%s`\n", + name); + if (GNUNET_OK != + GNUNET_PQ_exec_statements (pg->conn, + es)) + { + TALER_LOG_ERROR ("Failed to start transaction\n"); + GNUNET_break (0); + return GNUNET_SYSERR; + } + pg->transaction_name = name; + return GNUNET_OK; +} + + /** * Roll back the current transaction of a database connection. * @@ -16021,6 +16060,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) plugin->setup_foreign_servers = &postgres_setup_foreign_servers; plugin->start = &postgres_start; plugin->start_read_committed = &postgres_start_read_committed; + plugin->start_read_only = &postgres_start_read_only; plugin->commit = &postgres_commit; plugin->preflight = &postgres_preflight; plugin->rollback = &postgres_rollback; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 48f0ff993..c3661d83b 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -2844,6 +2844,18 @@ struct TALER_EXCHANGEDB_Plugin (*start_read_committed)(void *cls, const char *name); + /** + * Start a READ ONLY serializable transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging) + * must point to a constant + * @return #GNUNET_OK on success + */ + enum GNUNET_GenericReturnValue + (*start_read_only)(void *cls, + const char *name); + /** * Commit a transaction. -- cgit v1.2.3