gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: complete implementation of long-


From: gnunet
Subject: [taler-exchange] branch master updated: complete implementation of long-polling for reserve status; remove support for multi-threaded exchange httpd
Date: Mon, 23 Aug 2021 00:00:41 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new c559b1c9 complete implementation of long-polling for reserve status; 
remove support for multi-threaded exchange httpd
c559b1c9 is described below

commit c559b1c935a93c4cdec442beeac59264d483c824
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Aug 23 00:00:32 2021 +0200

    complete implementation of long-polling for reserve status; remove support 
for multi-threaded exchange httpd
---
 src/auditor/report-lib.c                           |   31 +-
 src/auditor/report-lib.h                           |    5 -
 src/auditor/taler-auditor-httpd.c                  |  503 ++------
 .../taler-auditor-httpd_deposit-confirmation.c     |    1 -
 src/auditor/taler-auditor-sync.c                   |   51 +-
 src/auditor/taler-helper-auditor-aggregation.c     |    5 -
 src/auditor/taler-helper-auditor-coins.c           |   13 -
 src/auditor/taler-helper-auditor-deposits.c        |    1 -
 src/auditor/taler-helper-auditor-reserves.c        |    7 -
 src/auditor/taler-helper-auditor-wire.c            |   23 +-
 src/bank-lib/bank_api_admin.c                      |    1 -
 src/exchange/Makefile.am                           |    5 +-
 src/exchange/taler-exchange-aggregator.c           |   63 +-
 src/exchange/taler-exchange-closer.c               |   55 +-
 src/exchange/taler-exchange-httpd.c                |  554 +++------
 src/exchange/taler-exchange-httpd.h                |    2 +-
 src/exchange/taler-exchange-httpd_auditors.c       |    5 -
 src/exchange/taler-exchange-httpd_db.c             |   17 +-
 src/exchange/taler-exchange-httpd_db.h             |    4 -
 src/exchange/taler-exchange-httpd_deposit.c        |    9 -
 src/exchange/taler-exchange-httpd_deposits_get.c   |    3 -
 src/exchange/taler-exchange-httpd_keys.c           |   99 +-
 src/exchange/taler-exchange-httpd_link.c           |    3 -
 src/exchange/taler-exchange-httpd_loop.c           |  209 ----
 src/exchange/taler-exchange-httpd_loop.h           |   60 -
 .../taler-exchange-httpd_management_auditors.c     |    5 -
 ...exchange-httpd_management_auditors_AP_disable.c |    4 -
 ...nge-httpd_management_denominations_HDP_revoke.c |    1 -
 .../taler-exchange-httpd_management_post_keys.c    |    6 -
 ...r-exchange-httpd_management_signkey_EP_revoke.c |    1 -
 .../taler-exchange-httpd_management_wire_disable.c |    4 -
 .../taler-exchange-httpd_management_wire_enable.c  |    5 -
 .../taler-exchange-httpd_management_wire_fees.c    |    4 -
 src/exchange/taler-exchange-httpd_melt.c           |   10 -
 src/exchange/taler-exchange-httpd_recoup.c         |   11 +-
 .../taler-exchange-httpd_refreshes_reveal.c        |   10 -
 src/exchange/taler-exchange-httpd_refund.c         |    5 -
 src/exchange/taler-exchange-httpd_reserves_get.c   |   24 +-
 src/exchange/taler-exchange-httpd_transfers_get.c  |    4 -
 src/exchange/taler-exchange-httpd_withdraw.c       |    6 -
 src/exchange/taler-exchange-transfer.c             |   46 +-
 src/exchange/taler-exchange-wirewatch.c            |   35 +-
 src/exchange/test_taler_exchange_httpd_restart.sh  |  107 --
 src/exchangedb/irbt_callbacks.c                    |  117 +-
 src/exchangedb/plugin_exchangedb_postgres.c        | 1291 +++++---------------
 src/exchangedb/test_exchangedb.c                   |  184 +--
 src/include/taler_exchange_service.h               |    5 +-
 src/include/taler_exchangedb_plugin.h              |  230 +---
 src/include/taler_mhd_lib.h                        |   29 +
 src/include/taler_testing_lib.h                    |    4 -
 src/lib/exchange_api_reserves_get.c                |   75 +-
 src/mhd/Makefile.am                                |    3 +-
 src/mhd/mhd_config.c                               |   47 +
 src/mhd/mhd_run.c                                  |  174 +++
 src/testing/test_taler_exchange_aggregator.c       |   12 +-
 src/testing/testing_api_cmd_insert_deposit.c       |   16 +-
 src/testing/testing_api_cmd_status.c               |    1 +
 src/testing/testing_api_helpers_exchange.c         |    3 +-
 58 files changed, 1113 insertions(+), 3095 deletions(-)

diff --git a/src/auditor/report-lib.c b/src/auditor/report-lib.c
index 5f45d719..0ae1cc1f 100644
--- a/src/auditor/report-lib.c
+++ b/src/auditor/report-lib.c
@@ -41,11 +41,6 @@ struct TALER_Amount TALER_ARL_currency_round_unit;
  */
 const struct GNUNET_CONFIGURATION_Handle *TALER_ARL_cfg;
 
-/**
- * Our session with the #TALER_ARL_edb.
- */
-struct TALER_EXCHANGEDB_Session *TALER_ARL_esession;
-
 /**
  * Handle to access the auditor's database.
  */
@@ -213,7 +208,6 @@ TALER_ARL_get_denomination_info_by_hash (
     denominations = GNUNET_CONTAINER_multihashmap_create (256,
                                                           GNUNET_NO);
     qs = TALER_ARL_edb->iterate_denomination_info (TALER_ARL_edb->cls,
-                                                   TALER_ARL_esession,
                                                    &add_denomination,
                                                    NULL);
     if (0 > qs)
@@ -239,7 +233,6 @@ TALER_ARL_get_denomination_info_by_hash (
     struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
 
     qs = TALER_ARL_edb->get_denomination_info (TALER_ARL_edb->cls,
-                                               TALER_ARL_esession,
                                                dh,
                                                &issue);
     if (qs <= 0)
@@ -324,23 +317,24 @@ transact (TALER_ARL_Analysis analysis,
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  TALER_ARL_edb->preflight (TALER_ARL_edb->cls,
-                            TALER_ARL_esession);
+  if (GNUNET_OK !=
+      TALER_ARL_edb->preflight (TALER_ARL_edb->cls))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
   ret = TALER_ARL_edb->start (TALER_ARL_edb->cls,
-                              TALER_ARL_esession,
                               "auditor");
   if (GNUNET_OK != ret)
   {
     GNUNET_break (0);
-    TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
-                             TALER_ARL_esession);
+    TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
     return GNUNET_SYSERR;
   }
   qs = analysis (analysis_cls);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
   {
-    qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls,
-                                TALER_ARL_esession);
+    qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls);
     if (0 > qs)
     {
       GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -367,8 +361,7 @@ transact (TALER_ARL_Analysis analysis,
                 "Processing failed (or no changes), rolling back 
transaction\n");
     TALER_ARL_adb->rollback (TALER_ARL_adb->cls,
                              TALER_ARL_asession);
-    TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
-                             TALER_ARL_esession);
+    TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
   }
   switch (qs)
   {
@@ -396,11 +389,11 @@ int
 TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana,
                                   void *ana_cls)
 {
-  TALER_ARL_esession = TALER_ARL_edb->get_session (TALER_ARL_edb->cls);
-  if (NULL == TALER_ARL_esession)
+  if (GNUNET_OK !=
+      TALER_ARL_edb->preflight (TALER_ARL_edb->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to initialize exchange session.\n");
+                "Failed to initialize exchange connection.\n");
     return GNUNET_SYSERR;
   }
   TALER_ARL_asession = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
diff --git a/src/auditor/report-lib.h b/src/auditor/report-lib.h
index 5df990cf..d8d82591 100644
--- a/src/auditor/report-lib.h
+++ b/src/auditor/report-lib.h
@@ -54,11 +54,6 @@ extern struct TALER_Amount TALER_ARL_currency_round_unit;
  */
 extern const struct GNUNET_CONFIGURATION_Handle *TALER_ARL_cfg;
 
-/**
- * Our session with the #TALER_ARL_edb.
- */
-extern struct TALER_EXCHANGEDB_Session *TALER_ARL_esession;
-
 /**
  * Handle to access the auditor's database.
  */
diff --git a/src/auditor/taler-auditor-httpd.c 
b/src/auditor/taler-auditor-httpd.c
index 57165ef0..47d61866 100644
--- a/src/auditor/taler-auditor-httpd.c
+++ b/src/auditor/taler-auditor-httpd.c
@@ -61,9 +61,9 @@
 static int auditor_connection_close;
 
 /**
- * The auditor's configuration (global)
+ * The auditor's configuration.
  */
-static struct GNUNET_CONFIGURATION_Handle *cfg;
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
  * Our DB plugin.
@@ -86,187 +86,20 @@ static struct TALER_AuditorPublicKeyP auditor_pub;
 static unsigned int connection_timeout = 30;
 
 /**
- * The HTTP Daemon.
+ * Return value from main()
  */
-static struct MHD_Daemon *mhd;
+static int global_ret;
 
 /**
  * Port to run the daemon on.
  */
 static uint16_t serve_port;
 
-/**
- * Path for the unix domain-socket to run the daemon on.
- */
-static char *serve_unixpath;
-
-/**
- * File mode for unix-domain socket.
- */
-static mode_t unixpath_mode;
-
 /**
  * Our currency.
  */
 char *TAH_currency;
 
-/**
- * Pipe used for signaling reloading of our key state.
- */
-static int reload_pipe[2] = { -1, -1 };
-
-
-/**
- * Handle a signal, writing relevant signal numbers to the pipe.
- *
- * @param signal_number the signal number
- */
-static void
-handle_signal (int signal_number)
-{
-  char c = signal_number;
-
-  (void) ! write (reload_pipe[1],
-                  &c,
-                  1);
-  /* While one might like to "handle errors" here, even logging via fprintf()
-     isn't safe inside of a signal handler. So there is nothing we safely CAN
-     do. OTOH, also very little that can go wrong in practice. Calling _exit()
-     on errors might be a possibility, but that might do more harm than good. 
*///
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigint (void)
-{
-  handle_signal (SIGINT);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigterm (void)
-{
-  handle_signal (SIGTERM);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sighup (void)
-{
-  handle_signal (SIGHUP);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigchld (void)
-{
-  handle_signal (SIGCHLD);
-}
-
-
-/**
- * Read signals from a pipe in a loop, and reload keys from disk if
- * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
- * restart if SIGHUP is received.
- *
- * @return #GNUNET_SYSERR on errors,
- *         #GNUNET_OK to terminate normally
- *         #GNUNET_NO to restart an update version of the binary
- */
-static int
-signal_loop (void)
-{
-  struct GNUNET_SIGNAL_Context *sigterm;
-  struct GNUNET_SIGNAL_Context *sigint;
-  struct GNUNET_SIGNAL_Context *sighup;
-  struct GNUNET_SIGNAL_Context *sigchld;
-  int ret;
-
-  if (0 != pipe (reload_pipe))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                         "pipe");
-    return GNUNET_SYSERR;
-  }
-  sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
-                                           &handle_sigterm);
-  sigint = GNUNET_SIGNAL_handler_install (SIGINT,
-                                          &handle_sigint);
-  sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
-                                          &handle_sighup);
-  sigchld = GNUNET_SIGNAL_handler_install (SIGCHLD,
-                                           &handle_sigchld);
-
-  ret = 2;
-  while (2 == ret)
-  {
-    char c;
-    ssize_t res;
-
-    errno = 0;
-    res = read (reload_pipe[0],
-                &c,
-                1);
-    if ( (res < 0) &&
-         (EINTR != errno))
-    {
-      GNUNET_break (0);
-      ret = GNUNET_SYSERR;
-      break;
-    }
-    if (EINTR == errno)
-    {
-      /* ignore, do the loop again */
-      continue;
-    }
-    switch (c)
-    {
-    case SIGTERM:
-    case SIGINT:
-      /* terminate */
-      ret = GNUNET_OK;
-      break;
-    case SIGHUP:
-      /* restart updated binary */
-      ret = GNUNET_NO;
-      break;
-#if HAVE_DEVELOPER
-    case SIGCHLD:
-      /* running in test-mode, test finished, terminate */
-      ret = GNUNET_OK;
-      break;
-#endif
-    default:
-      /* unexpected character */
-      GNUNET_break (0);
-      break;
-    }
-  }
-  GNUNET_SIGNAL_handler_uninstall (sigterm);
-  GNUNET_SIGNAL_handler_uninstall (sigint);
-  GNUNET_SIGNAL_handler_uninstall (sighup);
-  GNUNET_SIGNAL_handler_uninstall (sigchld);
-  GNUNET_break (0 == close (reload_pipe[0]));
-  GNUNET_break (0 == close (reload_pipe[1]));
-  return ret;
-}
-
 
 /**
  * Function called whenever MHD is done with a request.  If the
@@ -435,7 +268,7 @@ handle_mhd_request (void *cls,
  *
  * @return #GNUNET_OK on success
  */
-static int
+static enum GNUNET_GenericReturnValue
 auditor_serve_process_config (void)
 {
   if (NULL ==
@@ -452,13 +285,11 @@ auditor_serve_process_config (void)
                 "Failed to initialize DB subsystem to query exchange 
database\n");
     return GNUNET_SYSERR;
   }
-  if (GNUNET_OK !=
-      TALER_MHD_parse_config (cfg,
-                              "auditor",
-                              &serve_port,
-                              &serve_unixpath,
-                              &unixpath_mode))
+  if (GNUNET_SYSERR ==
+      TAH_eplugin->preflight (TAH_eplugin->cls))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to initialize DB subsystem to query exchange 
database\n");
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
@@ -533,6 +364,113 @@ auditor_serve_process_config (void)
 }
 
 
+/**
+ * Function run on shutdown.
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+  struct MHD_Daemon *mhd;
+  (void) cls;
+
+  mhd = TALER_MHD_daemon_stop ();
+  TEAH_DEPOSIT_CONFIRMATION_done ();
+  if (NULL != mhd)
+    MHD_stop_daemon (mhd);
+  if (NULL != TAH_plugin)
+  {
+    TALER_AUDITORDB_plugin_unload (TAH_plugin);
+    TAH_plugin = NULL;
+  }
+  if (NULL != TAH_eplugin)
+  {
+    TALER_EXCHANGEDB_plugin_unload (TAH_eplugin);
+    TAH_eplugin = NULL;
+  }
+}
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be
+ *        NULL!)
+ * @param config configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *config)
+{
+  enum TALER_MHD_GlobalOptions go;
+  int fh;
+
+  go = TALER_MHD_GO_NONE;
+  if (auditor_connection_close)
+    go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
+  TALER_MHD_setup (go);
+  cfg = config;
+
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
+  if (GNUNET_OK !=
+      auditor_serve_process_config ())
+  {
+    global_ret = EXIT_NOTCONFIGURED;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  TEAH_DEPOSIT_CONFIRMATION_init ();
+  fh = TALER_MHD_bind (cfg,
+                       "auditor",
+                       &serve_port);
+  if ( (0 == serve_port) &&
+       (-1 == fh) )
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  {
+    struct MHD_Daemon *mhd;
+
+    mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME
+                            | MHD_USE_PIPE_FOR_SHUTDOWN
+                            | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
+                            | MHD_USE_TCP_FASTOPEN,
+                            (-1 == fh) ? serve_port : 0,
+                            NULL, NULL,
+                            &handle_mhd_request, NULL,
+                            MHD_OPTION_LISTEN_BACKLOG_SIZE,
+                            (unsigned int) 1024,
+                            MHD_OPTION_LISTEN_SOCKET,
+                            fh,
+                            MHD_OPTION_EXTERNAL_LOGGER,
+                            &TALER_MHD_handle_logs,
+                            NULL,
+                            MHD_OPTION_NOTIFY_COMPLETED,
+                            &handle_mhd_completion_callback,
+                            NULL,
+                            MHD_OPTION_CONNECTION_TIMEOUT,
+                            connection_timeout,
+                            MHD_OPTION_END);
+    if (NULL == mhd)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed to launch HTTP service. Is the port in use?\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+    global_ret = EXIT_SUCCESS;
+    TALER_MHD_daemon_start (mhd);
+  }
+}
+
+
 /**
  * The main function of the taler-auditor-httpd server ("the auditor").
  *
@@ -544,15 +482,11 @@ int
 main (int argc,
       char *const *argv)
 {
-  char *cfgfile = NULL;
-  char *loglev = NULL;
-  char *logfile = NULL;
   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_option_flag ('C',
                                "connection-close",
                                "force HTTP connections to be closed after each 
request",
                                &auditor_connection_close),
-    GNUNET_GETOPT_option_cfgfile (&cfgfile),
     GNUNET_GETOPT_option_uint ('t',
                                "timeout",
                                "SECONDS",
@@ -560,207 +494,22 @@ main (int argc,
                                &connection_timeout),
     GNUNET_GETOPT_option_help (
       "HTTP server providing a RESTful API to access a Taler auditor"),
-    GNUNET_GETOPT_option_loglevel (&loglev),
-    GNUNET_GETOPT_option_logfile (&logfile),
     GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
     GNUNET_GETOPT_OPTION_END
   };
   int ret;
-  const char *listen_pid;
-  const char *listen_fds;
-  int fh = -1;
-  enum TALER_MHD_GlobalOptions go;
 
   TALER_OS_init ();
-  {
-    int ret;
-
-    ret = GNUNET_GETOPT_run ("taler-auditor-httpd",
-                             options,
-                             argc, argv);
-    if (GNUNET_NO == ret)
-      return EXIT_SUCCESS;
-    if (GNUNET_SYSERR == ret)
-      return EXIT_FAILURE;
-  }
-  go = TALER_MHD_GO_NONE;
-  if (auditor_connection_close)
-    go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
-  TALER_MHD_setup (go);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_log_setup ("taler-auditor-httpd",
-                                   (NULL == loglev) ? "INFO" : loglev,
-                                   logfile));
-  if (NULL == cfgfile)
-    cfgfile = GNUNET_CONFIGURATION_default_filename ();
-  if (NULL == cfgfile)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Can't find default configuration file.\n");
-    return EXIT_NOTCONFIGURED;
-  }
-  cfg = GNUNET_CONFIGURATION_create ();
-  if (GNUNET_SYSERR ==
-      GNUNET_CONFIGURATION_load (cfg,
-                                 cfgfile))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Malformed configuration file `%s', exiting ...\n",
-                cfgfile);
-    GNUNET_free (cfgfile);
-    return EXIT_NOTCONFIGURED;
-  }
-  GNUNET_free (cfgfile);
-
-  if (GNUNET_OK !=
-      auditor_serve_process_config ())
-    return EXIT_NOTCONFIGURED;
-  TEAH_DEPOSIT_CONFIRMATION_init ();
-  /* check for systemd-style FD passing */
-  listen_pid = getenv ("LISTEN_PID");
-  listen_fds = getenv ("LISTEN_FDS");
-  if ( (NULL != listen_pid) &&
-       (NULL != listen_fds) &&
-       (getpid () == strtol (listen_pid,
-                             NULL,
-                             10)) &&
-       (1 == strtoul (listen_fds,
-                      NULL,
-                      10)) )
-  {
-    int flags;
-
-    fh = 3;
-    flags = fcntl (fh,
-                   F_GETFD);
-    if ( (-1 == flags) &&
-         (EBADF == errno) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Bad listen socket passed, ignored\n");
-      fh = -1;
-    }
-    flags |= FD_CLOEXEC;
-    if ( (-1 != fh) &&
-         (0 != fcntl (fh,
-                      F_SETFD,
-                      flags)) )
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                           "fcntl");
-  }
-
-  /* consider unix path */
-  if ( (-1 == fh) &&
-       (NULL != serve_unixpath) )
-  {
-    fh = TALER_MHD_open_unix_path (serve_unixpath,
-                                   unixpath_mode);
-    if (-1 == fh)
-    {
-      TEAH_DEPOSIT_CONFIRMATION_done ();
-      return EXIT_NOPERMISSION; /* most likely at least */
-    }
-  }
-
-  mhd = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN
-                          | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
-                          | MHD_USE_INTERNAL_POLLING_THREAD
-                          | MHD_USE_TCP_FASTOPEN,
-                          (-1 == fh) ? serve_port : 0,
-                          NULL, NULL,
-                          &handle_mhd_request, NULL,
-                          MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 32,
-                          MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024,
-                          MHD_OPTION_LISTEN_SOCKET, fh,
-                          MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
-                          NULL,
-                          MHD_OPTION_NOTIFY_COMPLETED,
-                          &handle_mhd_completion_callback, NULL,
-                          MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
-                          MHD_OPTION_END);
-  if (NULL == mhd)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to start HTTP server.\n");
-    TEAH_DEPOSIT_CONFIRMATION_done ();
-    return EXIT_FAILURE;
-  }
-
-  /* normal behavior */
-  ret = signal_loop ();
-  switch (ret)
-  {
-  case GNUNET_OK:
-  case GNUNET_SYSERR:
-    MHD_stop_daemon (mhd);
-    break;
-  case GNUNET_NO:
-    {
-      MHD_socket sock = MHD_quiesce_daemon (mhd);
-      pid_t chld;
-      int flags;
-
-      /* Set flags to make 'sock' inherited by child */
-      flags = fcntl (sock, F_GETFD);
-      GNUNET_assert (-1 != flags);
-      flags &= ~FD_CLOEXEC;
-      GNUNET_assert (-1 != fcntl (sock, F_SETFD, flags));
-      chld = fork ();
-      if (-1 == chld)
-      {
-        /* fork() failed, continue clean up, unhappily */
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                             "fork");
-      }
-      if (0 == chld)
-      {
-        char pids[12];
-
-        /* exec another taler-auditor-httpd, passing on the listen socket;
-           as in systemd it is expected to be on FD #3 */
-        if (3 != dup2 (sock, 3))
-        {
-          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                               "dup2");
-          _exit (1);
-        }
-        /* Tell the child that it is the desired recipient for FD #3 */
-        GNUNET_snprintf (pids,
-                         sizeof (pids),
-                         "%u",
-                         getpid ());
-        setenv ("LISTEN_PID", pids, 1);
-        setenv ("LISTEN_FDS", "1", 1);
-        /* Finally, exec the (presumably) more recent auditor binary */
-        execvp ("taler-auditor-httpd",
-                argv);
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                             "execvp");
-        _exit (1);
-      }
-      /* we're the original process, handle remaining contextions
-         before exiting; as the listen socket is no longer used,
-         close it here */
-      GNUNET_break (0 == close (sock));
-      while (0 != MHD_get_daemon_info (mhd,
-                                       MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->
-             num_connections)
-        sleep (1);
-      /* Now we're really done, practice clean shutdown */
-      MHD_stop_daemon (mhd);
-    }
-    break;
-  default:
-    GNUNET_break (0);
-    MHD_stop_daemon (mhd);
-    break;
-  }
-  TALER_AUDITORDB_plugin_unload (TAH_plugin);
-  TAH_plugin = NULL;
-  TALER_EXCHANGEDB_plugin_unload (TAH_eplugin);
-  TAH_eplugin = NULL;
-  TEAH_DEPOSIT_CONFIRMATION_done ();
-  return (GNUNET_SYSERR == ret) ? EXIT_FAILURE : EXIT_SUCCESS;
+  ret = GNUNET_PROGRAM_run (argc, argv,
+                            "taler-auditor-httpd",
+                            "Taler auditor HTTP service",
+                            options,
+                            &run, NULL);
+  if (GNUNET_SYSERR == ret)
+    return EXIT_INVALIDARGUMENT;
+  if (GNUNET_NO == ret)
+    return EXIT_SUCCESS;
+  return global_ret;
 }
 
 
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c 
b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 9632f0cc..f38e8ee7 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -147,7 +147,6 @@ verify_and_execute_deposit_confirmation (
 
     /* check for revocation */
     qs = TAH_eplugin->lookup_signkey_revocation (TAH_eplugin->cls,
-                                                 NULL,
                                                  &es->exchange_pub,
                                                  &master_sig);
     if (0 > qs)
diff --git a/src/auditor/taler-auditor-sync.c b/src/auditor/taler-auditor-sync.c
index 79135230..0dfaa19a 100644
--- a/src/auditor/taler-auditor-sync.c
+++ b/src/auditor/taler-auditor-sync.c
@@ -119,11 +119,6 @@ static struct Table tables[] = {
  */
 struct InsertContext
 {
-  /**
-   * Database session to use.
-   */
-  struct TALER_EXCHANGEDB_Session *ds;
-
   /**
    * Table we are replicating.
    */
@@ -154,7 +149,6 @@ do_insert (void *cls,
   if (0 >= ctx->qs)
     return GNUNET_SYSERR;
   qs = dst->insert_records_by_table (dst->cls,
-                                     ctx->ds,
                                      td);
   if (0 >= qs)
   {
@@ -193,42 +187,34 @@ do_insert (void *cls,
  *
  * @return #GNUNET_OK on success, #GNUNET_SYSERR to rollback
  */
-static int
-transact (struct TALER_EXCHANGEDB_Session *ss,
-          struct TALER_EXCHANGEDB_Session *ds)
+static enum GNUNET_GenericReturnValue
+transact (void)
 {
   struct InsertContext ctx = {
-    .ds = ds,
     .qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
   };
 
   if (0 >
       src->start (src->cls,
-                  ss,
                   "lookup src serials"))
     return GNUNET_SYSERR;
   for (unsigned int i = 0; ! tables[i].end; i++)
     src->lookup_serial_by_table (src->cls,
-                                 ss,
                                  tables[i].rt,
                                  &tables[i].end_serial);
   if (0 >
-      src->commit (src->cls,
-                   ss))
+      src->commit (src->cls))
     return GNUNET_SYSERR;
   if (GNUNET_OK !=
       dst->start (src->cls,
-                  ds,
                   "lookup dst serials"))
     return GNUNET_SYSERR;
   for (unsigned int i = 0; ! tables[i].end; i++)
     dst->lookup_serial_by_table (dst->cls,
-                                 ds,
                                  tables[i].rt,
                                  &tables[i].start_serial);
   if (0 >
-      dst->commit (dst->cls,
-                   ds))
+      dst->commit (dst->cls))
     return GNUNET_SYSERR;
   for (unsigned int i = 0; ! tables[i].end; i++)
   {
@@ -248,16 +234,13 @@ transact (struct TALER_EXCHANGEDB_Session *ss,
 
       if (GNUNET_OK !=
           src->start (src->cls,
-                      ss,
                       "copy table (src)"))
         return GNUNET_SYSERR;
       if (GNUNET_OK !=
           dst->start (dst->cls,
-                      ds,
                       "copy table (dst)"))
         return GNUNET_SYSERR;
       qs = src->lookup_records_by_table (src->cls,
-                                         ss,
                                          table->rt,
                                          table->start_serial,
                                          &do_insert,
@@ -290,10 +273,8 @@ transact (struct TALER_EXCHANGEDB_Session *ss,
       }
       if (0 == ctx.qs)
         return GNUNET_SYSERR; /* insertion failed, maybe record existed? try 
again */
-      src->rollback (src->cls,
-                     ss);
-      qs = dst->commit (dst->cls,
-                        ds);
+      src->rollback (src->cls);
+      qs = dst->commit (dst->cls);
       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -328,35 +309,29 @@ static void
 do_sync (void *cls)
 {
   static struct GNUNET_TIME_Relative delay;
-  struct TALER_EXCHANGEDB_Session *ss;
-  struct TALER_EXCHANGEDB_Session *ds;
 
   sync_task = NULL;
   actual_size = 0;
-  ss = src->get_session (src->cls);
-  if (NULL == ss)
+  if (GNUNET_SYSERR ==
+      src->preflight (src->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failed to begin transaction with data source. Exiting\n");
     return;
   }
-  ds = dst->get_session (dst->cls);
-  if (NULL == ds)
+  if (GNUNET_SYSERR ==
+      dst->preflight (dst->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failed to begin transaction with data destination. 
Exiting\n");
     return;
   }
-  if (GNUNET_OK !=
-      transact (ss,
-                ds))
+  if (GNUNET_OK != transact ())
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Transaction failed, rolling back\n");
-    src->rollback (src->cls,
-                   ss);
-    dst->rollback (dst->cls,
-                   ds);
+    src->rollback (src->cls);
+    dst->rollback (dst->cls);
   }
   if (0 != global_ret)
   {
diff --git a/src/auditor/taler-helper-auditor-aggregation.c 
b/src/auditor/taler-helper-auditor-aggregation.c
index c6398be2..3bc8c770 100644
--- a/src/auditor/taler-helper-auditor-aggregation.c
+++ b/src/auditor/taler-helper-auditor-aggregation.c
@@ -756,7 +756,6 @@ wire_transfer_information_cb (
 
   /* Obtain coin's transaction history */
   qs = TALER_ARL_edb->get_coin_transactions (TALER_ARL_edb->cls,
-                                             TALER_ARL_esession,
                                              coin_pub,
                                              GNUNET_YES,
                                              &tl);
@@ -770,7 +769,6 @@ wire_transfer_information_cb (
     return;
   }
   qs = TALER_ARL_edb->get_known_coin (TALER_ARL_edb->cls,
-                                      TALER_ARL_esession,
                                       coin_pub,
                                       &coin);
   if (qs <= 0)
@@ -946,7 +944,6 @@ get_wire_fee (struct AggregationContext *ac,
   wfi = GNUNET_new (struct WireFeeInfo);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       TALER_ARL_edb->get_wire_fee (TALER_ARL_edb->cls,
-                                   TALER_ARL_esession,
                                    method,
                                    timestamp,
                                    &wfi->start_date,
@@ -1083,7 +1080,6 @@ check_wire_out_cb (void *cls,
     return GNUNET_SYSERR;
   }
   qs = TALER_ARL_edb->lookup_wire_transfer (TALER_ARL_edb->cls,
-                                            TALER_ARL_esession,
                                             wtid,
                                             &wire_transfer_information_cb,
                                             &wcc);
@@ -1258,7 +1254,6 @@ analyze_aggregations (void *cls)
   ac.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
   qs = TALER_ARL_edb->select_wire_out_above_serial_id (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     ppa.last_wire_out_serial_id,
     &check_wire_out_cb,
     &ac);
diff --git a/src/auditor/taler-helper-auditor-coins.c 
b/src/auditor/taler-helper-auditor-coins.c
index b3050542..a2c8b8ce 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -476,7 +476,6 @@ check_coin_history (const struct TALER_CoinSpendPublicKeyP 
*coin_pub,
   int have_refund;
 
   qs = TALER_ARL_edb->get_coin_transactions (TALER_ARL_edb->cls,
-                                             TALER_ARL_esession,
                                              coin_pub,
                                              GNUNET_YES,
                                              &tl);
@@ -717,7 +716,6 @@ init_denomination (const struct GNUNET_HashCode *denom_hash,
               TALER_amount2s (&ds->denom_balance),
               (unsigned long long) ds->num_issued);
   qs = TALER_ARL_edb->get_denomination_revocation (TALER_ARL_edb->cls,
-                                                   TALER_ARL_esession,
                                                    denom_hash,
                                                    &msig,
                                                    &rowid);
@@ -878,7 +876,6 @@ sync_denomination (void *cls,
                 TALER_amount2s (&ds->denom_balance),
                 (unsigned long long) ds->num_issued);
     cnt = TALER_ARL_edb->count_known_coins (TALER_ARL_edb->cls,
-                                            TALER_ARL_esession,
                                             denom_hash);
     if (0 > cnt)
     {
@@ -1187,7 +1184,6 @@ check_known_coin (const char *operation,
               "Checking denomination signature on %s\n",
               TALER_B2S (coin_pub));
   qs = TALER_ARL_edb->get_known_coin (TALER_ARL_edb->cls,
-                                      TALER_ARL_esession,
                                       coin_pub,
                                       &ci);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
@@ -1336,7 +1332,6 @@ refresh_session_cb (void *cls,
     };
 
     qs = TALER_ARL_edb->get_refresh_reveal (TALER_ARL_edb->cls,
-                                            TALER_ARL_esession,
                                             rc,
                                             &reveal_data_cb,
                                             &reveal_ctx);
@@ -2250,7 +2245,6 @@ check_denomination (
   struct TALER_AuditorSignatureP auditor_sig;
 
   qs = TALER_ARL_edb->select_auditor_denom_sig (TALER_ARL_edb->cls,
-                                                TALER_ARL_esession,
                                                 &issue->denom_hash,
                                                 &TALER_ARL_auditor_pub,
                                                 &auditor_sig);
@@ -2329,7 +2323,6 @@ analyze_coins (void *cls)
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Checking denominations...\n");
   qs = TALER_ARL_edb->iterate_denomination_info (TALER_ARL_edb->cls,
-                                                 TALER_ARL_esession,
                                                  &check_denomination,
                                                  NULL);
   if (0 > qs)
@@ -2389,7 +2382,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_withdrawals_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_withdraw_serial_id,
          &withdraw_cb,
          &cc)) )
@@ -2404,7 +2396,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_refunds_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_refund_serial_id,
          &refund_cb,
          &cc)))
@@ -2419,7 +2410,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_recoup_refresh_serial_id,
          &recoup_refresh_cb,
          &cc)))
@@ -2432,7 +2422,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_recoup_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_recoup_serial_id,
          &recoup_cb,
          &cc)))
@@ -2447,7 +2436,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_refreshes_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_melt_serial_id,
          &refresh_session_cb,
          &cc)))
@@ -2462,7 +2450,6 @@ analyze_coins (void *cls)
   if (0 >
       (qs = TALER_ARL_edb->select_deposits_above_serial_id (
          TALER_ARL_edb->cls,
-         TALER_ARL_esession,
          ppc.last_deposit_serial_id,
          &deposit_cb,
          &cc)))
diff --git a/src/auditor/taler-helper-auditor-deposits.c 
b/src/auditor/taler-helper-auditor-deposits.c
index c9c8bf66..58b41fbc 100644
--- a/src/auditor/taler-helper-auditor-deposits.c
+++ b/src/auditor/taler-helper-auditor-deposits.c
@@ -123,7 +123,6 @@ test_dc (void *cls,
     struct TALER_Amount deposit_fee;
 
     qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls,
-                                      TALER_ARL_esession,
                                       &dep,
                                       GNUNET_NO /* do not check refund 
deadline */,
                                       &deposit_fee,
diff --git a/src/auditor/taler-helper-auditor-reserves.c 
b/src/auditor/taler-helper-auditor-reserves.c
index efeaa4f6..592663da 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -744,7 +744,6 @@ handle_recoup_by_reserve (
   if (NULL == rev)
   {
     qs = TALER_ARL_edb->get_denomination_revocation (TALER_ARL_edb->cls,
-                                                     TALER_ARL_esession,
                                                      &coin->denom_pub_hash,
                                                      &msig,
                                                      &rev_rowid);
@@ -882,7 +881,6 @@ get_closing_fee (const char *receiver_account,
               method);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       TALER_ARL_edb->get_wire_fee (TALER_ARL_edb->cls,
-                                   TALER_ARL_esession,
                                    method,
                                    atime,
                                    &start_date,
@@ -1089,7 +1087,6 @@ verify_reserve_balance (void *cls,
 
     reserve.pub = rs->reserve_pub;
     qs = TALER_ARL_edb->reserves_get (TALER_ARL_edb->cls,
-                                      TALER_ARL_esession,
                                       &reserve);
     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
     {
@@ -1377,7 +1374,6 @@ analyze_reserves (void *cls)
 
   qs = TALER_ARL_edb->select_reserves_in_above_serial_id (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     ppr.last_reserve_in_serial_id,
     &handle_reserve_in,
     &rc);
@@ -1388,7 +1384,6 @@ analyze_reserves (void *cls)
   }
   qs = TALER_ARL_edb->select_withdrawals_above_serial_id (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     ppr.last_reserve_out_serial_id,
     &handle_reserve_out,
     &rc);
@@ -1399,7 +1394,6 @@ analyze_reserves (void *cls)
   }
   qs = TALER_ARL_edb->select_recoup_above_serial_id (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     ppr.last_reserve_recoup_serial_id,
     &handle_recoup_by_reserve,
     &rc);
@@ -1410,7 +1404,6 @@ analyze_reserves (void *cls)
   }
   qs = TALER_ARL_edb->select_reserve_closed_above_serial_id (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     ppr.last_reserve_close_serial_id,
     &handle_reserve_closed,
     &rc);
diff --git a/src/auditor/taler-helper-auditor-wire.c 
b/src/auditor/taler-helper-auditor-wire.c
index eee186ca..13ee27b7 100644
--- a/src/auditor/taler-helper-auditor-wire.c
+++ b/src/auditor/taler-helper-auditor-wire.c
@@ -665,8 +665,7 @@ commit (enum GNUNET_DB_QueryStatus qs)
                   "Hard error, not recording progress\n");
     TALER_ARL_adb->rollback (TALER_ARL_adb->cls,
                              TALER_ARL_asession);
-    TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
-                             TALER_ARL_esession);
+    TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
     return qs;
   }
   for (struct WireAccount *wa = wa_head;
@@ -741,8 +740,7 @@ commit (enum GNUNET_DB_QueryStatus qs)
 
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
   {
-    qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls,
-                                TALER_ARL_esession);
+    qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls);
     if (0 > qs)
     {
       GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -769,8 +767,7 @@ commit (enum GNUNET_DB_QueryStatus qs)
                 "Processing failed, rolling back transaction\n");
     TALER_ARL_adb->rollback (TALER_ARL_adb->cls,
                              TALER_ARL_asession);
-    TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
-                             TALER_ARL_esession);
+    TALER_ARL_edb->rollback (TALER_ARL_edb->cls);
   }
   return qs;
 }
@@ -870,7 +867,6 @@ check_for_required_transfers (void)
               "Analyzing exchange's unfinished deposits (deadline: %s)\n",
               GNUNET_STRINGS_absolute_time_to_string (next_timestamp));
   qs = TALER_ARL_edb->select_deposits_missing_wire (TALER_ARL_edb->cls,
-                                                    TALER_ARL_esession,
                                                     pp.last_timestamp,
                                                     next_timestamp,
                                                     &wire_missing_cb,
@@ -1267,7 +1263,6 @@ check_exchange_wire_out (struct WireAccount *wa)
               wa->ai->section_name);
   qs = TALER_ARL_edb->select_wire_out_above_serial_id_by_account (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     wa->ai->section_name,
     wa->pp.last_wire_out_serial_id,
     &wire_out_cb,
@@ -1824,7 +1819,6 @@ process_credits (void *cls)
               wa->ai->section_name);
   qs = TALER_ARL_edb->select_reserves_in_above_serial_id_by_account (
     TALER_ARL_edb->cls,
-    TALER_ARL_esession,
     wa->ai->section_name,
     wa->pp.last_reserve_in_serial_id,
     &reserve_in_cb,
@@ -1953,11 +1947,11 @@ reserve_closed_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 begin_transaction (void)
 {
-  TALER_ARL_esession = TALER_ARL_edb->get_session (TALER_ARL_edb->cls);
-  if (NULL == TALER_ARL_esession)
+  if (GNUNET_OK !=
+      TALER_ARL_edb->preflight (TALER_ARL_edb->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to initialize exchange database session.\n");
+                "Failed to initialize exchange database connection.\n");
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   TALER_ARL_asession = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
@@ -1974,11 +1968,9 @@ begin_transaction (void)
     GNUNET_break (0);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
-  TALER_ARL_edb->preflight (TALER_ARL_edb->cls,
-                            TALER_ARL_esession);
+  TALER_ARL_edb->preflight (TALER_ARL_edb->cls);
   if (GNUNET_OK !=
       TALER_ARL_edb->start (TALER_ARL_edb->cls,
-                            TALER_ARL_esession,
                             "wire auditor"))
   {
     GNUNET_break (0);
@@ -2031,7 +2023,6 @@ begin_transaction (void)
 
     qs = TALER_ARL_edb->select_reserve_closed_above_serial_id (
       TALER_ARL_edb->cls,
-      TALER_ARL_esession,
       pp.last_reserve_close_uuid,
       &reserve_closed_cb,
       NULL);
diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c
index 96d568f6..d1a05297 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin.c
@@ -226,7 +226,6 @@ TALER_BANK_admin_add_incoming (
   {
     GNUNET_free (aai);
     json_decref (admin_obj);
-    GNUNET_break (0);
     return NULL;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 4c1f26df..1f53b012 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -84,7 +84,6 @@ taler_exchange_httpd_SOURCES = \
   taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \
   taler-exchange-httpd_keys.c taler-exchange-httpd_keys.h \
   taler-exchange-httpd_link.c taler-exchange-httpd_link.h \
-  taler-exchange-httpd_loop.c taler-exchange-httpd_loop.h \
   taler-exchange-httpd_management.h \
   taler-exchange-httpd_management_auditors.c \
   taler-exchange-httpd_management_auditors_AP_disable.c \
@@ -122,7 +121,6 @@ taler_exchange_httpd_LDADD = \
   -lgnunetjson \
   -ljansson \
   -lz \
-  -lpthread \
   $(XLIB)
 
 # Testcases
@@ -130,8 +128,7 @@ taler_exchange_httpd_LDADD = \
 AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export 
PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
 
 check_SCRIPTS = \
-  test_taler_exchange_httpd.sh \
-  test_taler_exchange_httpd_restart.sh
+  test_taler_exchange_httpd.sh
 if HAVE_EXPENSIVE_TESTS
 check_SCRIPTS += \
   test_taler_exchange_httpd_afl.sh
diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index 5da0a809..c82b6666 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -89,11 +89,6 @@ struct AggregationUnit
    */
   const struct TALER_EXCHANGEDB_AccountInfo *wa;
 
-  /**
-   * Database session for all of our transactions.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
-
   /**
    * Array of row_ids from the aggregation.
    */
@@ -355,7 +350,6 @@ deposit_cb (void *cls,
   au->total_amount = *amount_with_fee;
   au->have_refund = GNUNET_NO;
   qs = db_plugin->select_refunds_by_coin (db_plugin->cls,
-                                          au->session,
                                           coin_pub,
                                           &au->merchant_pub,
                                           h_contract_terms,
@@ -444,7 +438,6 @@ deposit_cb (void *cls,
     enum GNUNET_DB_QueryStatus qs;
 
     qs = db_plugin->get_wire_fee (db_plugin->cls,
-                                  au->session,
                                   au->wa->method,
                                   au->execution_time,
                                   &start_date,
@@ -468,7 +461,6 @@ deposit_cb (void *cls,
               TALER_B2S (&au->wtid),
               TALER_amount2s (&au->wire_fee));
   qs = db_plugin->insert_aggregation_tracking (db_plugin->cls,
-                                               au->session,
                                                &au->wtid,
                                                row_id);
   if (qs <= 0)
@@ -480,7 +472,6 @@ deposit_cb (void *cls,
               "Aggregator marks deposit %llu as done\n",
               (unsigned long long) row_id);
   qs = db_plugin->mark_deposit_done (db_plugin->cls,
-                                     au->session,
                                      row_id);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
   {
@@ -535,7 +526,6 @@ aggregate_cb (void *cls,
   /* compute contribution of this coin (after fees) */
   au->have_refund = GNUNET_NO;
   qs = db_plugin->select_refunds_by_coin (db_plugin->cls,
-                                          au->session,
                                           coin_pub,
                                           &au->merchant_pub,
                                           h_contract_terms,
@@ -596,7 +586,6 @@ aggregate_cb (void *cls,
   au->additional_rows[au->rows_offset++] = row_id;
   /* insert into aggregation tracking table */
   qs = db_plugin->insert_aggregation_tracking (db_plugin->cls,
-                                               au->session,
                                                &au->wtid,
                                                row_id);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
@@ -605,7 +594,6 @@ aggregate_cb (void *cls,
     return qs;
   }
   qs = db_plugin->mark_deposit_done (db_plugin->cls,
-                                     au->session,
                                      row_id);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
   {
@@ -622,16 +610,14 @@ aggregate_cb (void *cls,
 /**
  * Perform a database commit. If it fails, print a warning.
  *
- * @param session session to perform the commit for.
  * @return status of commit
  */
 static enum GNUNET_DB_QueryStatus
-commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
+commit_or_warn (void)
 {
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = db_plugin->commit (db_plugin->cls,
-                          session);
+  qs = db_plugin->commit (db_plugin->cls);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     return qs;
   GNUNET_log ((GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -652,24 +638,23 @@ static void
 run_aggregation (void *cls)
 {
   struct AggregationUnit au_active;
-  struct TALER_EXCHANGEDB_Session *session;
   enum GNUNET_DB_QueryStatus qs;
 
   (void) cls;
   task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Checking for ready deposits to aggregate\n");
-  if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
+  if (GNUNET_SYSERR ==
+      db_plugin->preflight (db_plugin->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to obtain database session!\n");
+                "Failed to obtain database connection!\n");
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
   if (GNUNET_OK !=
-      db_plugin->start_deferred_wire_out (db_plugin->cls,
-                                          session))
+      db_plugin->start_deferred_wire_out (db_plugin->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failed to start database transaction!\n");
@@ -680,16 +665,13 @@ run_aggregation (void *cls)
   memset (&au_active,
           0,
           sizeof (au_active));
-  au_active.session = session;
   qs = db_plugin->get_ready_deposit (db_plugin->cls,
-                                     session,
                                      &deposit_cb,
                                      &au_active);
   if (0 >= qs)
   {
     cleanup_au (&au_active);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -729,7 +711,6 @@ run_aggregation (void *cls)
               "Found ready deposit for %s, aggregating\n",
               TALER_B2S (&au_active.merchant_pub));
   qs = db_plugin->iterate_matching_deposits (db_plugin->cls,
-                                             session,
                                              &au_active.h_wire,
                                              &au_active.merchant_pub,
                                              &aggregate_cb,
@@ -741,8 +722,7 @@ run_aggregation (void *cls)
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failed to execute deposit iteration!\n");
     cleanup_au (&au_active);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
@@ -752,8 +732,7 @@ run_aggregation (void *cls)
     /* serializiability issue, try again */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Serialization issue, trying again later!\n");
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     cleanup_au (&au_active);
     GNUNET_assert (NULL == task);
     task = GNUNET_SCHEDULER_add_now (&run_aggregation,
@@ -780,14 +759,12 @@ run_aggregation (void *cls)
                 TALER_amount2s (&au_active.final_amount));
     /* Rollback ongoing transaction, as we will not use the respective
        WTID and thus need to remove the tracking data */
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
 
     /* There were results, just the value was too low.  Start another
        transaction to mark all* of the selected deposits as minor! */
     if (GNUNET_OK !=
         db_plugin->start (db_plugin->cls,
-                          session,
                           "aggregator mark tiny transactions"))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -799,14 +776,12 @@ run_aggregation (void *cls)
     }
     /* Mark transactions by row_id as minor */
     qs = db_plugin->mark_deposit_tiny (db_plugin->cls,
-                                       session,
                                        au_active.row_id);
     if (0 <= qs)
     {
       for (unsigned int i = 0; i<au_active.rows_offset; i++)
       {
         qs = db_plugin->mark_deposit_tiny (db_plugin->cls,
-                                           session,
                                            au_active.additional_rows[i]);
         if (0 > qs)
           break;
@@ -816,8 +791,7 @@ run_aggregation (void *cls)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Serialization issue, trying again later!\n");
-      db_plugin->rollback (db_plugin->cls,
-                           session);
+      db_plugin->rollback (db_plugin->cls);
       cleanup_au (&au_active);
       /* start again */
       GNUNET_assert (NULL == task);
@@ -827,15 +801,14 @@ run_aggregation (void *cls)
     }
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
-      db_plugin->rollback (db_plugin->cls,
-                           session);
+      db_plugin->rollback (db_plugin->cls);
       cleanup_au (&au_active);
       global_ret = EXIT_FAILURE;
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
     /* commit */
-    (void) commit_or_warn (session);
+    (void) commit_or_warn ();
     cleanup_au (&au_active);
 
     /* start again */
@@ -877,7 +850,6 @@ run_aggregation (void *cls)
                 (unsigned int) buf_size);
     /* Commit our intention to execute the wire transfer! */
     qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
-                                              session,
                                               au_active.wa->method,
                                               buf,
                                               buf_size);
@@ -887,7 +859,6 @@ run_aggregation (void *cls)
      table constraints */
   if (qs >= 0)
     qs = db_plugin->store_wire_transfer_out (db_plugin->cls,
-                                             session,
                                              au_active.execution_time,
                                              &au_active.wtid,
                                              au_active.wire,
@@ -899,8 +870,7 @@ run_aggregation (void *cls)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Serialization issue for prepared wire data; trying again 
later!\n");
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     /* start again */
     GNUNET_assert (NULL == task);
     task = GNUNET_SCHEDULER_add_now (&run_aggregation,
@@ -910,8 +880,7 @@ run_aggregation (void *cls)
   if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   {
     GNUNET_break (0);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     /* die hard */
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
@@ -923,7 +892,7 @@ run_aggregation (void *cls)
 
   /* Now we can finally commit the overall transaction, as we are
      again consistent if all of this passes. */
-  switch (commit_or_warn (session))
+  switch (commit_or_warn ())
   {
   case GNUNET_DB_STATUS_SOFT_ERROR:
     /* try again */
diff --git a/src/exchange/taler-exchange-closer.c 
b/src/exchange/taler-exchange-closer.c
index 89e43999..926c9355 100644
--- a/src/exchange/taler-exchange-closer.c
+++ b/src/exchange/taler-exchange-closer.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2016-2020 Taler Systems SA
+  Copyright (C) 2016-2021 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -174,16 +174,14 @@ parse_wirewatch_config (void)
 /**
  * Perform a database commit. If it fails, print a warning.
  *
- * @param session session to perform the commit for.
  * @return status of commit
  */
 static enum GNUNET_DB_QueryStatus
-commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
+commit_or_warn (void)
 {
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = db_plugin->commit (db_plugin->cls,
-                          session);
+  qs = db_plugin->commit (db_plugin->cls);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     return qs;
   GNUNET_log ((GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -194,27 +192,13 @@ commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
 }
 
 
-/**
- * Closure for #expired_reserve_cb().
- */
-struct ExpiredReserveContext
-{
-
-  /**
-   * Database session we are using.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
-
-};
-
-
 /**
  * Function called with details about expired reserves.
  * We trigger the reserve closure by inserting the respective
  * closing record and prewire instructions into the respective
  * tables.
  *
- * @param cls a `struct ExpiredReserveContext *`
+ * @param cls NULL
  * @param reserve_pub public key of the reserve
  * @param left amount left in the reserve
  * @param account_payto_uri information about the bank account that initially
@@ -229,8 +213,6 @@ expired_reserve_cb (void *cls,
                     const char *account_payto_uri,
                     struct GNUNET_TIME_Absolute expiration_date)
 {
-  struct ExpiredReserveContext *erc = cls;
-  struct TALER_EXCHANGEDB_Session *session = erc->session;
   struct GNUNET_TIME_Absolute now;
   struct TALER_WireTransferIdentifierRawP wtid;
   struct TALER_Amount amount_without_fee;
@@ -239,6 +221,7 @@ expired_reserve_cb (void *cls,
   enum GNUNET_DB_QueryStatus qs;
   const struct TALER_EXCHANGEDB_AccountInfo *wa;
 
+  (void) cls;
   /* NOTE: potential optimization: use custom SQL API to not
      fetch this: */
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -269,7 +252,6 @@ expired_reserve_cb (void *cls,
     enum GNUNET_DB_QueryStatus qs;
 
     qs = db_plugin->get_wire_fee (db_plugin->cls,
-                                  session,
                                   wa->method,
                                   expiration_date,
                                   &start_date,
@@ -326,7 +308,6 @@ expired_reserve_cb (void *cls,
                       sizeof (*reserve_pub)));
   if (GNUNET_SYSERR != ret)
     qs = db_plugin->insert_reserve_closed (db_plugin->cls,
-                                           session,
                                            reserve_pub,
                                            now,
                                            account_payto_uri,
@@ -356,7 +337,7 @@ expired_reserve_cb (void *cls,
     /* Reserve balance was almost zero OR soft error */
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Reserve was virtually empty, moving on\n");
-    (void) commit_or_warn (session);
+    (void) commit_or_warn ();
     return qs;
   }
 
@@ -373,7 +354,6 @@ expired_reserve_cb (void *cls,
                                  &buf_size);
     /* Commit our intention to execute the wire transfer! */
     qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
-                                              session,
                                               wa->method,
                                               buf,
                                               buf_size);
@@ -404,17 +384,16 @@ expired_reserve_cb (void *cls,
 static void
 run_reserve_closures (void *cls)
 {
-  struct TALER_EXCHANGEDB_Session *session;
   enum GNUNET_DB_QueryStatus qs;
-  struct ExpiredReserveContext erc;
   struct GNUNET_TIME_Absolute now;
 
   (void) cls;
   task = NULL;
-  if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
+  if (GNUNET_SYSERR ==
+      db_plugin->preflight (db_plugin->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to obtain database session!\n");
+                "Failed to obtain database connection!\n");
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
@@ -422,7 +401,6 @@ run_reserve_closures (void *cls)
 
   if (GNUNET_OK !=
       db_plugin->start (db_plugin->cls,
-                        session,
                         "aggregator reserve closures"))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -431,30 +409,26 @@ run_reserve_closures (void *cls)
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  erc.session = session;
   now = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&now);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Checking for reserves to close by date %s\n",
               GNUNET_STRINGS_absolute_time_to_string (now));
   qs = db_plugin->get_expired_reserves (db_plugin->cls,
-                                        session,
                                         now,
                                         &expired_reserve_cb,
-                                        &erc);
+                                        NULL);
   GNUNET_assert (1 >= qs);
   switch (qs)
   {
   case GNUNET_DB_STATUS_HARD_ERROR:
     GNUNET_break (0);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
   case GNUNET_DB_STATUS_SOFT_ERROR:
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     GNUNET_assert (NULL == task);
     task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
                                      NULL);
@@ -462,8 +436,7 @@ run_reserve_closures (void *cls)
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "No more idle reserves to close, going to sleep.\n");
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     GNUNET_assert (NULL == task);
     if (GNUNET_YES == test_mode)
     {
@@ -477,7 +450,7 @@ run_reserve_closures (void *cls)
     }
     return;
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
-    (void) commit_or_warn (session);
+    (void) commit_or_warn ();
     GNUNET_assert (NULL == task);
     task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
                                      NULL);
diff --git a/src/exchange/taler-exchange-httpd.c 
b/src/exchange/taler-exchange-httpd.c
index c06695e4..627ac00f 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2020 Taler Systems SA
+  Copyright (C) 2014-2021 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -34,7 +34,6 @@
 #include "taler-exchange-httpd_deposits_get.h"
 #include "taler-exchange-httpd_keys.h"
 #include "taler-exchange-httpd_link.h"
-#include "taler-exchange-httpd_loop.h"
 #include "taler-exchange-httpd_management.h"
 #include "taler-exchange-httpd_melt.h"
 #include "taler-exchange-httpd_mhd.h"
@@ -53,7 +52,7 @@
 /**
  * Backlog for listen operation on unix domain sockets.
  */
-#define UNIX_BACKLOG 500
+#define UNIX_BACKLOG 50
 
 
 /**
@@ -67,7 +66,7 @@ int TEH_allow_keys_timetravel;
 /**
  * The exchange's configuration (global)
  */
-struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
+const struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
 
 /**
  * How long is caching /keys allowed at most? (global)
@@ -101,33 +100,20 @@ char *TEH_currency;
 static unsigned int connection_timeout = 30;
 
 /**
- * How many threads to use.
- * The default value (0) sets the actual number of threads
- * based on the number of available cores.
+ * -C command-line flag given?
  */
-static unsigned int num_threads = 0;
+static int connection_close;
 
 /**
- * The HTTP Daemon.
+ * Value to return from main()
  */
-static struct MHD_Daemon *mhd;
+static int global_ret;
 
 /**
  * Port to run the daemon on.
  */
 static uint16_t serve_port;
 
-/**
- * Path for the unix domain-socket
- * to run the daemon on.
- */
-static char *serve_unixpath;
-
-/**
- * File mode for unix-domain socket.
- */
-static mode_t unixpath_mode;
-
 /**
  * Counter for the number of requests this HTTP has processed so far.
  */
@@ -302,11 +288,8 @@ handle_mhd_completion_callback (void *cls,
 
   TALER_MHD_parse_post_cleanup_callback (rc->opaque_post_parsing_context);
   /* Sanity-check that we didn't leave any transactions hanging */
-  /* NOTE: In high-performance production, we could consider
-     removing this as it should not be needed and might be costly
-     (to be benchmarked). */
-  TEH_plugin->preflight (TEH_plugin->cls,
-                         TEH_plugin->get_session (TEH_plugin->cls));
+  GNUNET_break (GNUNET_OK ==
+                TEH_plugin->preflight (TEH_plugin->cls));
   GNUNET_free (rc);
   *con_cls = NULL;
   GNUNET_async_scope_restore (&old_scope);
@@ -1179,18 +1162,6 @@ exchange_serve_process_config (void)
                 "Failed to initialize DB subsystem\n");
     return GNUNET_SYSERR;
   }
-
-  if (GNUNET_OK !=
-      TALER_MHD_parse_config (TEH_cfg,
-                              "exchange",
-                              &serve_port,
-                              &serve_unixpath,
-                              &unixpath_mode))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to setup HTTPd subsystem\n");
-    return GNUNET_SYSERR;
-  }
   return GNUNET_OK;
 }
 
@@ -1248,16 +1219,11 @@ write_stats (void)
 /* Developer logic for supporting the `-f' option. */
 #if HAVE_DEVELOPER
 
-
 /**
  * Option `-f' (specifies an input file to give to the HTTP server).
  */
 static char *input_filename;
 
-/**
- * We finished handling the request and should now terminate.
- */
-static int do_terminate;
 
 /**
  * Run 'nc' or 'ncat' as a fake HTTP client using #input_filename
@@ -1277,7 +1243,8 @@ run_fake_client (void)
                    "-"))
     fd = STDIN_FILENO;
   else
-    fd = open (input_filename, O_RDONLY);
+    fd = open (input_filename,
+               O_RDONLY);
   if (-1 == fd)
   {
     fprintf (stderr,
@@ -1324,6 +1291,50 @@ run_fake_client (void)
 }
 
 
+/**
+ * Run the exchange to serve a single request only, without threads.
+ *
+ * @return #GNUNET_OK on success
+ */
+static void
+run_single_request (void)
+{
+  pid_t xfork;
+
+  xfork = fork ();
+  if (-1 == xfork)
+  {
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (0 == xfork)
+  {
+    pid_t cld;
+
+    cld = run_fake_client ();
+    if (-1 == cld)
+      _exit (EXIT_FAILURE);
+    _exit (EXIT_SUCCESS);
+  }
+
+  {
+    int status;
+
+    if (xfork != waitpid (xfork,
+                          &status,
+                          0))
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Waiting for `nc' child failed: %s\n",
+                  strerror (errno));
+  }
+}
+
+
+/* end of HAVE_DEVELOPER */
+#endif
+
+
 /**
  * Signature of the callback used by MHD to notify the application
  * about completed connections.  If we are running in test-mode with
@@ -1344,240 +1355,138 @@ connection_done (void *cls,
   (void) cls;
   (void) connection;
   (void) socket_context;
+
+#if HAVE_DEVELOPER
   /* We only act if the connection is closed. */
   if (MHD_CONNECTION_NOTIFY_CLOSED != toe)
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Connection done!\n");
-  do_terminate = GNUNET_YES;
+  if (NULL != input_filename)
+    GNUNET_SCHEDULER_shutdown ();
+#endif
 }
 
 
 /**
- * Run the exchange to serve a single request only, without threads.
+ * Function run on shutdown.
  *
- * @return #GNUNET_OK on success
+ * @param cls NULL
  */
-static int
-run_single_request (void)
+static void
+do_shutdown (void *cls)
 {
-  pid_t cld;
-  int status;
-
-  /* run only the testfile input, then terminate */
-  mhd
-    = MHD_start_daemon (MHD_USE_PIPE_FOR_SHUTDOWN
-                        | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
-                        | MHD_USE_TCP_FASTOPEN,
-                        0, /* pick free port */
-                        NULL, NULL,
-                        &handle_mhd_request, NULL,
-                        MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 10,
-                        MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
-                        NULL,
-                        MHD_OPTION_NOTIFY_COMPLETED,
-                        &handle_mhd_completion_callback, NULL,
-                        MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
-                        MHD_OPTION_NOTIFY_CONNECTION, &connection_done, NULL,
-                        MHD_OPTION_END);
-  if (NULL == mhd)
-  {
-    fprintf (stderr,
-             "Failed to start HTTP server.\n");
-    return GNUNET_SYSERR;
-  }
-  serve_port = MHD_get_daemon_info (mhd,
-                                    MHD_DAEMON_INFO_BIND_PORT)->port;
-  cld = run_fake_client ();
-  if (-1 == cld)
-    return GNUNET_SYSERR;
-  /* run the event loop until #connection_done() was called */
-  while (GNUNET_NO == do_terminate)
-  {
-    fd_set rs;
-    fd_set ws;
-    fd_set es;
-    struct timeval tv;
-    MHD_UNSIGNED_LONG_LONG timeout;
-    int maxsock = -1;
-    int have_tv;
-
-    FD_ZERO (&rs);
-    FD_ZERO (&ws);
-    FD_ZERO (&es);
-    if (MHD_YES !=
-        MHD_get_fdset (mhd,
-                       &rs,
-                       &ws,
-                       &es,
-                       &maxsock))
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    have_tv = MHD_get_timeout (mhd,
-                               &timeout);
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = 1000 * (timeout % 1000);
-    if (-1 == select (maxsock + 1,
-                      &rs,
-                      &ws,
-                      &es,
-                      have_tv ? &tv : NULL))
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    MHD_run (mhd);
-  }
-  {
-    MHD_socket sock = MHD_quiesce_daemon (mhd);
+  struct MHD_Daemon *mhd;
+  (void) cls;
 
-    TEH_resume_keys_requests (true);
-    TEH_reserves_get_cleanup ();
+  mhd = TALER_MHD_daemon_stop ();
+  TEH_resume_keys_requests (true);
+  TEH_reserves_get_cleanup ();
+  if (NULL != mhd)
     MHD_stop_daemon (mhd);
-    GNUNET_break (0 == close (sock));
-  }
-  mhd = NULL;
-  if (cld != waitpid (cld,
-                      &status,
-                      0))
-    fprintf (stderr,
-             "Waiting for `nc' child failed: %s\n",
-             strerror (errno));
-  return GNUNET_OK;
+  TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
+  TEH_WIRE_done ();
 }
 
 
-/* end of HAVE_DEVELOPER */
-#endif
-
-
 /**
- * Run the ordinary multi-threaded main loop and the logic to
- * wait for CTRL-C.
+ * Main function that will be run by the scheduler.
  *
- * @param fh listen socket
- * @param argv command line arguments
- * @return #GNUNET_OK on success
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be
+ *        NULL!)
+ * @param config configuration
  */
-static int
-run_main_loop (int fh,
-               char *const *argv)
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *config)
 {
-  int ret;
-
-  GNUNET_assert (0 < num_threads);
-
-  mhd
-    = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN
-                        | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
-                        | MHD_USE_INTERNAL_POLLING_THREAD
-                        | MHD_ALLOW_SUSPEND_RESUME
-                        | MHD_USE_TCP_FASTOPEN,
-                        (-1 == fh) ? serve_port : 0,
-                        NULL, NULL,
-                        &handle_mhd_request, NULL,
-                        MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 
num_threads,
-                        MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024,
-                        MHD_OPTION_LISTEN_SOCKET, fh,
-                        MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
-                        NULL,
-                        MHD_OPTION_NOTIFY_COMPLETED,
-                        &handle_mhd_completion_callback, NULL,
-                        MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
-                        MHD_OPTION_END);
-  if (NULL == mhd)
+  enum TALER_MHD_GlobalOptions go;
+  int fh;
+
+  go = TALER_MHD_GO_NONE;
+  if (connection_close)
+    go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
+  TALER_MHD_setup (go);
+  TEH_cfg = config;
+
+  if (GNUNET_OK !=
+      exchange_serve_process_config ())
   {
-    fprintf (stderr,
-             "Failed to start HTTP server.\n");
-    return GNUNET_SYSERR;
+    global_ret = EXIT_NOTCONFIGURED;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
   }
-
-  atexit (&write_stats);
-  ret = TEH_loop_run ();
-  switch (ret)
+  if (GNUNET_OK !=
+      TEH_WIRE_init ())
   {
-  case GNUNET_OK:
-  case GNUNET_SYSERR:
-    {
-      MHD_socket sock = MHD_quiesce_daemon (mhd);
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_OK !=
+      TEH_keys_init ())
+  {
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
 
-      TEH_resume_keys_requests (true);
-      TEH_reserves_get_cleanup ();
-      MHD_stop_daemon (mhd);
-      GNUNET_break (0 == close (sock));
-    }
-    mhd = NULL;
-    break;
-  case GNUNET_NO:
+  TEH_load_terms (TEH_cfg);
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
+  fh = TALER_MHD_bind (TEH_cfg,
+                       "exchange",
+                       &serve_port);
+  if ( (0 == serve_port) &&
+       (-1 == fh) )
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  {
+    struct MHD_Daemon *mhd;
+
+    mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME
+                            | MHD_USE_PIPE_FOR_SHUTDOWN
+                            | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
+                            | MHD_USE_TCP_FASTOPEN,
+                            (-1 == fh) ? serve_port : 0,
+                            NULL, NULL,
+                            &handle_mhd_request, NULL,
+                            MHD_OPTION_LISTEN_BACKLOG_SIZE,
+                            (unsigned int) 1024,
+                            MHD_OPTION_LISTEN_SOCKET,
+                            fh,
+                            MHD_OPTION_EXTERNAL_LOGGER,
+                            &TALER_MHD_handle_logs,
+                            NULL,
+                            MHD_OPTION_NOTIFY_COMPLETED,
+                            &handle_mhd_completion_callback,
+                            NULL,
+                            MHD_OPTION_NOTIFY_CONNECTION,
+                            &connection_done,
+                            NULL,
+                            MHD_OPTION_CONNECTION_TIMEOUT,
+                            connection_timeout,
+                            MHD_OPTION_END);
+    if (NULL == mhd)
     {
-      MHD_socket sock = MHD_quiesce_daemon (mhd);
-      pid_t chld;
-      int flags;
-
-      /* Set flags to make 'sock' inherited by child */
-      flags = fcntl (sock, F_GETFD);
-      GNUNET_assert (-1 != flags);
-      flags &= ~FD_CLOEXEC;
-      GNUNET_assert (-1 != fcntl (sock,
-                                  F_SETFD,
-                                  flags));
-      chld = fork ();
-      if (-1 == chld)
-      {
-        /* fork() failed, continue clean up, unhappily */
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                             "fork");
-      }
-      if (0 == chld)
-      {
-        char pids[12];
-
-        /* exec another taler-exchange-httpd, passing on the listen socket;
-           as in systemd it is expected to be on FD #3 */
-        if (3 != dup2 (sock, 3))
-        {
-          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                               "dup2");
-          _exit (1);
-        }
-        /* Tell the child that it is the desired recipient for FD #3 */
-        GNUNET_snprintf (pids,
-                         sizeof (pids),
-                         "%u",
-                         getpid ());
-        setenv ("LISTEN_PID", pids, 1);
-        setenv ("LISTEN_FDS", "1", 1);
-        /* Finally, exec the (presumably) more recent exchange binary */
-        execvp ("taler-exchange-httpd",
-                argv);
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                             "execvp");
-        _exit (1);
-      }
-      /* we're the original process, handle remaining contextions
-         before exiting; as the listen socket is no longer used,
-         close it here */
-      GNUNET_break (0 == close (sock));
-      while (0 != MHD_get_daemon_info (mhd,
-                                       MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->
-             num_connections)
-        sleep (1);
-      /* Now we're really done, practice clean shutdown */
-      TEH_resume_keys_requests (true);
-      TEH_reserves_get_cleanup ();
-      MHD_stop_daemon (mhd);
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed to launch HTTP service. Is the port in use?\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
     }
-    break;
-  default:
-    GNUNET_break (0);
-    TEH_resume_keys_requests (true);
-    MHD_stop_daemon (mhd);
-    break;
+    global_ret = EXIT_SUCCESS;
+    TALER_MHD_daemon_start (mhd);
   }
+  atexit (&write_stats);
 
-  return ret;
+#if HAVE_DEVELOPER
+  if (NULL != input_filename)
+    run_single_request ();
+#endif
 }
 
 
@@ -1592,10 +1501,6 @@ int
 main (int argc,
       char *const *argv)
 {
-  char *cfgfile = NULL;
-  char *loglev = NULL;
-  char *logfile = NULL;
-  int connection_close = GNUNET_NO;
   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_option_flag ('a',
                                "allow-timetravel",
@@ -1605,7 +1510,6 @@ main (int argc,
                                "connection-close",
                                "force HTTP connections to be closed after each 
request",
                                &connection_close),
-    GNUNET_GETOPT_option_cfgfile (&cfgfile),
     GNUNET_GETOPT_option_uint ('t',
                                "timeout",
                                "SECONDS",
@@ -1613,11 +1517,6 @@ main (int argc,
                                &connection_timeout),
     GNUNET_GETOPT_option_timetravel ('T',
                                      "timetravel"),
-    GNUNET_GETOPT_option_uint ('n',
-                               "num-threads",
-                               "NUM_THREADS",
-                               "size of the thread pool",
-                               &num_threads),
 #if HAVE_DEVELOPER
     GNUNET_GETOPT_option_filename ('f',
                                    "file-input",
@@ -1627,141 +1526,22 @@ main (int argc,
 #endif
     GNUNET_GETOPT_option_help (
       "HTTP server providing a RESTful API to access a Taler exchange"),
-    GNUNET_GETOPT_option_loglevel (&loglev),
-    GNUNET_GETOPT_option_logfile (&logfile),
     GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
     GNUNET_GETOPT_OPTION_END
   };
-  int ret;
-  const char *listen_pid;
-  const char *listen_fds;
-  int fh = -1;
-  enum TALER_MHD_GlobalOptions go;
+  enum GNUNET_GenericReturnValue ret;
 
   TALER_OS_init ();
-  ret = GNUNET_GETOPT_run ("taler-exchange-httpd",
-                           options,
-                           argc, argv);
+  ret = GNUNET_PROGRAM_run (argc, argv,
+                            "taler-exchange-httpd",
+                            "Taler exchange HTTP service",
+                            options,
+                            &run, NULL);
   if (GNUNET_SYSERR == ret)
     return EXIT_INVALIDARGUMENT;
   if (GNUNET_NO == ret)
     return EXIT_SUCCESS;
-  if (0 == num_threads)
-  {
-    cpu_set_t mask;
-    GNUNET_assert (0 ==
-                   sched_getaffinity (0,
-                                      sizeof (cpu_set_t),
-                                      &mask));
-    num_threads = CPU_COUNT (&mask);
-  }
-  go = TALER_MHD_GO_NONE;
-  if (connection_close)
-    go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
-  TALER_MHD_setup (go);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_log_setup ("taler-exchange-httpd",
-                                   (NULL == loglev) ? "INFO" : loglev,
-                                   logfile));
-  GNUNET_free (loglev);
-  GNUNET_free (logfile);
-  if (NULL == cfgfile)
-    cfgfile = GNUNET_CONFIGURATION_default_filename ();
-  if (NULL == cfgfile)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Can't find default configuration file.\n");
-    return EXIT_NOTCONFIGURED;
-  }
-
-  TEH_cfg = GNUNET_CONFIGURATION_create ();
-  if (GNUNET_SYSERR ==
-      GNUNET_CONFIGURATION_load (TEH_cfg,
-                                 cfgfile))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Malformed configuration file `%s', exit ...\n",
-                cfgfile);
-    GNUNET_free (cfgfile);
-    return EXIT_NOTCONFIGURED;
-  }
-  GNUNET_free (cfgfile);
-  if (GNUNET_OK !=
-      exchange_serve_process_config ())
-    return EXIT_NOTCONFIGURED;
-  TEH_load_terms (TEH_cfg);
-
-  /* check for systemd-style FD passing */
-  listen_pid = getenv ("LISTEN_PID");
-  listen_fds = getenv ("LISTEN_FDS");
-  if ( (NULL != listen_pid) &&
-       (NULL != listen_fds) &&
-       (getpid () == strtol (listen_pid,
-                             NULL,
-                             10)) &&
-       (1 == strtoul (listen_fds,
-                      NULL,
-                      10)) )
-  {
-    int flags;
-
-    fh = 3;
-    flags = fcntl (fh,
-                   F_GETFD);
-    if ( (-1 == flags) &&
-         (EBADF == errno) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Bad listen socket passed, ignored\n");
-      fh = -1;
-    }
-    flags |= FD_CLOEXEC;
-    if ( (-1 != fh) &&
-         (0 != fcntl (fh,
-                      F_SETFD,
-                      flags)) )
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                           "fcntl");
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Successfully obtained listen socket from hypervisor\n");
-  }
-
-  /* initialize #internal_key_state with an RC of 1 */
-  if (GNUNET_OK !=
-      TEH_WIRE_init ())
-    return EXIT_FAILURE;
-  if (GNUNET_OK !=
-      TEH_keys_init ())
-    return EXIT_FAILURE;
-  ret = TEH_loop_init ();
-  if (GNUNET_OK == ret)
-  {
-#if HAVE_DEVELOPER
-    if (NULL != input_filename)
-    {
-      ret = run_single_request ();
-    }
-    else
-#endif
-    {
-      /* consider unix path */
-      if ( (-1 == fh) &&
-           (NULL != serve_unixpath) )
-      {
-        fh = TALER_MHD_open_unix_path (serve_unixpath,
-                                       unixpath_mode);
-        if (-1 == fh)
-          return EXIT_NOPERMISSION; /* at least most likely */
-      }
-      ret = run_main_loop (fh,
-                           argv);
-    }
-    /* release signal handlers */
-    TEH_loop_done ();
-  }
-  TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
-  TEH_WIRE_done ();
-  return (GNUNET_SYSERR == ret) ? EXIT_FAILURE : EXIT_SUCCESS;
+  return global_ret;
 }
 
 
diff --git a/src/exchange/taler-exchange-httpd.h 
b/src/exchange/taler-exchange-httpd.h
index eaecc972..e4342648 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -42,7 +42,7 @@ extern struct GNUNET_TIME_Relative TEH_reserve_closing_delay;
 /**
  * The exchange's configuration.
  */
-extern struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
+extern const struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
 
 /**
  * Main directory with exchange data.
diff --git a/src/exchange/taler-exchange-httpd_auditors.c 
b/src/exchange/taler-exchange-httpd_auditors.c
index f3c061e3..34e640ad 100644
--- a/src/exchange/taler-exchange-httpd_auditors.c
+++ b/src/exchange/taler-exchange-httpd_auditors.c
@@ -65,7 +65,6 @@ struct AddAuditorDenomContext
  *
  * @param cls closure with a `struct AddAuditorDenomContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -73,7 +72,6 @@ struct AddAuditorDenomContext
 static enum GNUNET_DB_QueryStatus
 add_auditor_denom_sig (void *cls,
                        struct MHD_Connection *connection,
-                       struct TALER_EXCHANGEDB_Session *session,
                        MHD_RESULT *mhd_ret)
 {
   struct AddAuditorDenomContext *awc = cls;
@@ -84,7 +82,6 @@ add_auditor_denom_sig (void *cls,
 
   qs = TEH_plugin->lookup_denomination_key (
     TEH_plugin->cls,
-    session,
     awc->h_denom_pub,
     &meta);
   if (qs < 0)
@@ -110,7 +107,6 @@ add_auditor_denom_sig (void *cls,
 
   qs = TEH_plugin->lookup_auditor_status (
     TEH_plugin->cls,
-    session,
     awc->auditor_pub,
     &auditor_url,
     &enabled);
@@ -174,7 +170,6 @@ add_auditor_denom_sig (void *cls,
   GNUNET_free (auditor_url);
 
   qs = TEH_plugin->insert_auditor_denom_sig (TEH_plugin->cls,
-                                             session,
                                              awc->h_denom_pub,
                                              awc->auditor_pub,
                                              &awc->auditor_sig);
diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index 8574224a..3c693649 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -45,21 +45,18 @@
  *
  * @param coin the coin to make known
  * @param connection MHD request context
- * @param session database session and transaction to use
  * @param[out] mhd_ret set to MHD status on error
  * @return transaction status, negative on error (@a mhd_ret will be set in 
this case)
  */
 enum GNUNET_DB_QueryStatus
 TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
                      struct MHD_Connection *connection,
-                     struct TALER_EXCHANGEDB_Session *session,
                      MHD_RESULT *mhd_ret)
 {
   enum TALER_EXCHANGEDB_CoinKnownStatus cks;
 
   /* make sure coin is 'known' in database */
   cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
-                                       session,
                                        coin);
   switch (cks)
   {
@@ -85,7 +82,6 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
     enum GNUNET_DB_QueryStatus qs;
 
     qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
-                                            session,
                                             &coin->coin_pub,
                                             GNUNET_NO,
                                             &tl);
@@ -135,11 +131,10 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
                         TEH_DB_TransactionCallback cb,
                         void *cb_cls)
 {
-  struct TALER_EXCHANGEDB_Session *session;
-
   if (NULL != mhd_ret)
     *mhd_ret = -1; /* set to invalid value, to help detect bugs */
-  if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
+  if (GNUNET_OK !=
+      TEH_plugin->preflight (TEH_plugin->cls))
   {
     GNUNET_break (0);
     if (NULL != mhd_ret)
@@ -157,7 +152,6 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
 
     if (GNUNET_OK !=
         TEH_plugin->start (TEH_plugin->cls,
-                           session,
                            name))
     {
       GNUNET_break (0);
@@ -170,16 +164,13 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
     }
     qs = cb (cb_cls,
              connection,
-             session,
              mhd_ret);
     if (0 > qs)
-      TEH_plugin->rollback (TEH_plugin->cls,
-                            session);
+      TEH_plugin->rollback (TEH_plugin->cls);
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
       return GNUNET_SYSERR;
     if (0 <= qs)
-      qs = TEH_plugin->commit (TEH_plugin->cls,
-                               session);
+      qs = TEH_plugin->commit (TEH_plugin->cls);
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       if (NULL != mhd_ret)
diff --git a/src/exchange/taler-exchange-httpd_db.h 
b/src/exchange/taler-exchange-httpd_db.h
index 7e73340b..c115981d 100644
--- a/src/exchange/taler-exchange-httpd_db.h
+++ b/src/exchange/taler-exchange-httpd_db.h
@@ -31,14 +31,12 @@
  *
  * @param coin the coin to make known
  * @param connection MHD request context
- * @param session database session and transaction to use
  * @param[out] mhd_ret set to MHD status on error
  * @return transaction status, negative on error (@a mhd_ret will be set in 
this case)
  */
 enum GNUNET_DB_QueryStatus
 TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
                      struct MHD_Connection *connection,
-                     struct TALER_EXCHANGEDB_Session *session,
                      MHD_RESULT *mhd_ret);
 
 
@@ -52,7 +50,6 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
  *
  * @param cls closure
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -60,7 +57,6 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
 typedef enum GNUNET_DB_QueryStatus
 (*TEH_DB_TransactionCallback)(void *cls,
                               struct MHD_Connection *connection,
-                              struct TALER_EXCHANGEDB_Session *session,
                               MHD_RESULT *mhd_ret);
 
 
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index 5ea48c20..9c4cfdc7 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -133,14 +133,12 @@ struct DepositContext
  *
  * @param cls a `struct DepositContext`
  * @param connection MHD request context
- * @param session database session and transaction to use
  * @param[out] mhd_ret set to MHD status on error
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
 deposit_precheck (void *cls,
                   struct MHD_Connection *connection,
-                  struct TALER_EXCHANGEDB_Session *session,
                   MHD_RESULT *mhd_ret)
 {
   struct DepositContext *dc = cls;
@@ -149,7 +147,6 @@ deposit_precheck (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->have_deposit (TEH_plugin->cls,
-                                 session,
                                  deposit,
                                  GNUNET_YES /* check refund deadline */,
                                  &deposit_fee,
@@ -202,14 +199,12 @@ deposit_precheck (void *cls,
  *
  * @param cls a `struct DepositContext`
  * @param connection MHD request context
- * @param session database session and transaction to use
  * @param[out] mhd_ret set to MHD status on error
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
 deposit_transaction (void *cls,
                      struct MHD_Connection *connection,
-                     struct TALER_EXCHANGEDB_Session *session,
                      MHD_RESULT *mhd_ret)
 {
   struct DepositContext *dc = cls;
@@ -220,7 +215,6 @@ deposit_transaction (void *cls,
   /* make sure coin is 'known' in database */
   qs = TEH_make_coin_known (&deposit->coin,
                             connection,
-                            session,
                             mhd_ret);
   if (qs < 0)
     return qs;
@@ -230,7 +224,6 @@ deposit_transaction (void *cls,
      that we are in the transaction scope. */
   qs = deposit_precheck (cls,
                          connection,
-                         session,
                          mhd_ret);
   if (qs < 0)
     return qs;
@@ -244,7 +237,6 @@ deposit_transaction (void *cls,
     struct TALER_EXCHANGEDB_TransactionList *tl;
 
     qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
-                                            session,
                                             &deposit->coin.coin_pub,
                                             GNUNET_NO,
                                             &tl);
@@ -292,7 +284,6 @@ deposit_transaction (void *cls,
                                             tl);
   }
   qs = TEH_plugin->insert_deposit (TEH_plugin->cls,
-                                   session,
                                    dc->exchange_timestamp,
                                    deposit);
   if (GNUNET_DB_STATUS_HARD_ERROR == qs)
diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c 
b/src/exchange/taler-exchange-httpd_deposits_get.c
index f32b88b6..04e2acb0 100644
--- a/src/exchange/taler-exchange-httpd_deposits_get.c
+++ b/src/exchange/taler-exchange-httpd_deposits_get.c
@@ -203,7 +203,6 @@ handle_wtid_data (void *cls,
  *
  * @param cls closure of type `struct DepositWtidContext *`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -211,14 +210,12 @@ handle_wtid_data (void *cls,
 static enum GNUNET_DB_QueryStatus
 deposits_get_transaction (void *cls,
                           struct MHD_Connection *connection,
-                          struct TALER_EXCHANGEDB_Session *session,
                           MHD_RESULT *mhd_ret)
 {
   struct DepositWtidContext *ctx = cls;
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->lookup_transfer_by_deposit (TEH_plugin->cls,
-                                               session,
                                                &ctx->tps->h_contract_terms,
                                                &ctx->tps->h_wire,
                                                &ctx->tps->coin_pub,
diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index 216afd7c..f37aafbd 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -19,7 +19,6 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
-#include <pthread.h>
 #include "taler_json_lib.h"
 #include "taler_mhd_lib.h"
 #include "taler-exchange-httpd.h"
@@ -339,10 +338,9 @@ struct SuspendedKeysRequests
 
 
 /**
- * Thread-local.  Contains a pointer to `struct TEH_KeyStateHandle` or NULL.
- * Stores the per-thread latest generation of our key state.
+ * Stores the latest generation of our key state.
  */
-static pthread_key_t key_state;
+static struct TEH_KeyStateHandle *key_state;
 
 /**
  * Counter incremented whenever we have a reason to re-build the keys because
@@ -351,7 +349,7 @@ static pthread_key_t key_state;
  * changes, the variable MUST be volatile.  See #TEH_keys_get_state() and
  * #TEH_keys_update_states() for uses of this variable.
  */
-static volatile uint64_t key_generation;
+static uint64_t key_generation;
 
 /**
  * Head of DLL of suspended /keys requests.
@@ -391,29 +389,11 @@ static struct TALER_SecurityModulePublicKeyP denom_sm_pub;
  */
 static struct TALER_SecurityModulePublicKeyP esign_sm_pub;
 
-/**
- * Mutex protecting access to #denom_sm_pub and #esign_sm_pub.
- * (Could be split into two locks if ever needed.)
- */
-static pthread_mutex_t sm_pub_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Mutex protecting access to #skr_head and #skr_tail.
- * (Could be split into two locks if ever needed.)
- */
-static pthread_mutex_t skr_mutex = PTHREAD_MUTEX_INITIALIZER;
-
 /**
  * Are we shutting down?
  */
 static bool terminating;
 
-/**
- * Did we ever initialize #key_state?
- */
-static bool key_state_available;
-
-
 /**
  * Suspend /keys request while we (hopefully) are waiting to be
  * provisioned with key material.
@@ -427,10 +407,8 @@ suspend_request (struct MHD_Connection *connection)
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Suspending /keys request until key material changes\n");
-  GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
   if (terminating)
   {
-    GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
@@ -452,9 +430,9 @@ suspend_request (struct MHD_Connection *connection)
     skr_size--;
     skr_connection = skr->connection;
     MHD_resume_connection (skr->connection);
+    TALER_MHD_daemon_trigger ();
     GNUNET_free (skr);
   }
-  GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
   return MHD_YES;
 }
 
@@ -464,7 +442,6 @@ TEH_resume_keys_requests (bool do_shutdown)
 {
   struct SuspendedKeysRequests *skr;
 
-  GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
   if (do_shutdown)
     terminating = true;
   while (NULL != (skr = skr_head))
@@ -474,9 +451,9 @@ TEH_resume_keys_requests (bool do_shutdown)
                                  skr);
     skr_size--;
     MHD_resume_connection (skr->connection);
+    TALER_MHD_daemon_trigger ();
     GNUNET_free (skr);
   }
-  GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
 }
 
 
@@ -510,7 +487,6 @@ clear_response_cache (struct TEH_KeyStateHandle *ksh)
 static void
 check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
 {
-  GNUNET_assert (0 == pthread_mutex_lock (&sm_pub_mutex));
   if (0 !=
       GNUNET_memcmp (sm_pub,
                      &denom_sm_pub))
@@ -523,7 +499,6 @@ check_denom_sm_pub (const struct 
TALER_SecurityModulePublicKeyP *sm_pub)
     }
     denom_sm_pub = *sm_pub; /* TOFU ;-) */
   }
-  GNUNET_assert (0 == pthread_mutex_unlock (&sm_pub_mutex));
 }
 
 
@@ -536,7 +511,6 @@ check_denom_sm_pub (const struct 
TALER_SecurityModulePublicKeyP *sm_pub)
 static void
 check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
 {
-  GNUNET_assert (0 == pthread_mutex_lock (&sm_pub_mutex));
   if (0 !=
       GNUNET_memcmp (sm_pub,
                      &esign_sm_pub))
@@ -549,7 +523,6 @@ check_esign_sm_pub (const struct 
TALER_SecurityModulePublicKeyP *sm_pub)
     }
     esign_sm_pub = *sm_pub; /* TOFU ;-) */
   }
-  GNUNET_assert (0 == pthread_mutex_unlock (&sm_pub_mutex));
 }
 
 
@@ -896,38 +869,9 @@ destroy_key_state (struct TEH_KeyStateHandle *ksh,
 }
 
 
-/**
- * Free all resources associated with @a cls.  Called when
- * the respective pthread is destroyed.
- *
- * @param[in] cls a `struct TEH_KeyStateHandle`.
- */
-static void
-destroy_key_state_cb (void *cls)
-{
-  struct TEH_KeyStateHandle *ksh = cls;
-
-  destroy_key_state (ksh,
-                     true);
-}
-
-
-/**
- * Initialize keys submodule.
- *
- * @return #GNUNET_OK on success
- */
 int
 TEH_keys_init ()
 {
-  if (0 !=
-      pthread_key_create (&key_state,
-                          &destroy_key_state_cb))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  key_state_available = true;
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (TEH_cfg,
                                            "exchange",
@@ -949,11 +893,9 @@ TEH_keys_init ()
 void __attribute__ ((destructor))
 TEH_keys_finished ()
 {
-  if (key_state_available)
-  {
-    GNUNET_assert (0 ==
-                   pthread_key_delete (key_state));
-  }
+  if (NULL != key_state)
+    destroy_key_state (key_state,
+                       true);
 }
 
 
@@ -1799,22 +1741,14 @@ get_key_state (bool management_only)
   struct TEH_KeyStateHandle *old_ksh;
   struct TEH_KeyStateHandle *ksh;
 
-  GNUNET_assert (key_state_available);
-  old_ksh = pthread_getspecific (key_state);
+  old_ksh = key_state;
   if (NULL == old_ksh)
   {
     ksh = build_key_state (NULL,
                            management_only);
     if (NULL == ksh)
       return NULL;
-    if (0 != pthread_setspecific (key_state,
-                                  ksh))
-    {
-      GNUNET_break (0);
-      destroy_key_state (ksh,
-                         true);
-      return NULL;
-    }
+    key_state = ksh;
     return ksh;
   }
   if ( (old_ksh->key_generation < key_generation) ||
@@ -1826,15 +1760,7 @@ get_key_state (bool management_only)
                 (unsigned long long) key_generation);
     ksh = build_key_state (old_ksh->helpers,
                            management_only);
-    if (0 != pthread_setspecific (key_state,
-                                  ksh))
-    {
-      GNUNET_break (0);
-      if (NULL != ksh)
-        destroy_key_state (ksh,
-                           false);
-      return NULL;
-    }
+    key_state = ksh;
     old_ksh->helpers = NULL;
     destroy_key_state (old_ksh,
                        false);
@@ -2099,17 +2025,14 @@ TEH_keys_get_handler (struct TEH_RequestContext *rc,
     ksh = TEH_keys_get_state ();
     if (NULL == ksh)
     {
-      GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
       if ( (SKR_LIMIT == skr_size) &&
            (rc->connection == skr_connection) )
       {
-        GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
         return TALER_MHD_reply_with_error (rc->connection,
                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
                                            
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
                                            "too many connections suspended on 
/keys");
       }
-      GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
       return suspend_request (rc->connection);
     }
     krd = bsearch (&last_issue_date,
diff --git a/src/exchange/taler-exchange-httpd_link.c 
b/src/exchange/taler-exchange-httpd_link.c
index bbb02752..75d32e56 100644
--- a/src/exchange/taler-exchange-httpd_link.c
+++ b/src/exchange/taler-exchange-httpd_link.c
@@ -130,7 +130,6 @@ fail:
  *
  * @param cls closure
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -138,14 +137,12 @@ fail:
 static enum GNUNET_DB_QueryStatus
 link_transaction (void *cls,
                   struct MHD_Connection *connection,
-                  struct TALER_EXCHANGEDB_Session *session,
                   MHD_RESULT *mhd_ret)
 {
   struct HTD_Context *ctx = cls;
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->get_link_data (TEH_plugin->cls,
-                                  session,
                                   &ctx->coin_pub,
                                   &handle_link_data,
                                   ctx);
diff --git a/src/exchange/taler-exchange-httpd_loop.c 
b/src/exchange/taler-exchange-httpd_loop.c
deleted file mode 100644
index 086fbc87..00000000
--- a/src/exchange/taler-exchange-httpd_loop.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-  This file is part of TALER
-  Copyright (C) 2014--2020 Taler Systems SA
-
-  TALER is free software; you can redistribute it and/or modify it under the
-  terms of the GNU Affero General Public License as published by the Free 
Software
-  Foundation; either version 3, or (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
-
-  You should have received a copy of the GNU Affero General Public License 
along with
-  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_loop.c
- * @brief management of our main loop
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <pthread.h>
-#include "taler-exchange-httpd_loop.h"
-
-
-/* ************************* Signal logic ************************** */
-
-/**
- * Pipe used for signaling reloading of our key state.
- */
-static int reload_pipe[2] = { -1, -1 };
-
-
-/**
- * Handle a signal, writing relevant signal numbers to the pipe.
- *
- * @param signal_number the signal number
- */
-static void
-handle_signal (int signal_number)
-{
-  char c = (char) signal_number; /* never seen a signal_number > 127 on any 
platform */
-
-  (void) ! write (reload_pipe[1],
-                  &c,
-                  1);
-  /* While one might like to "handle errors" here, even logging via fprintf()
-     isn't safe inside of a signal handler. So there is nothing we safely CAN
-     do. OTOH, also very little that can go wrong in practice. Calling _exit()
-     on errors might be a possibility, but that might do more harm than good. 
*///
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigint (void)
-{
-  handle_signal (SIGINT);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigterm (void)
-{
-  handle_signal (SIGTERM);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sighup (void)
-{
-  handle_signal (SIGHUP);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigchld (void)
-{
-  handle_signal (SIGCHLD);
-}
-
-
-int
-TEH_loop_run (void)
-{
-  int ret;
-
-  ret = 2;
-  while (2 == ret)
-  {
-    char c;
-    ssize_t res;
-
-    errno = 0;
-    res = read (reload_pipe[0],
-                &c,
-                1);
-    if ((res < 0) && (EINTR != errno))
-    {
-      GNUNET_break (0);
-      ret = GNUNET_SYSERR;
-      break;
-    }
-    if (EINTR == errno)
-      continue;
-    switch (c)
-    {
-    case SIGTERM:
-    case SIGINT:
-      /* terminate */
-      ret = GNUNET_OK;
-      break;
-    case SIGHUP:
-      /* restart updated binary */
-      ret = GNUNET_NO;
-      break;
-#if HAVE_DEVELOPER
-    case SIGCHLD:
-      /* running in test-mode, test finished, terminate */
-      ret = GNUNET_OK;
-      break;
-#endif
-    default:
-      /* unexpected character */
-      GNUNET_break (0);
-      break;
-    }
-  }
-  return ret;
-}
-
-
-static struct GNUNET_SIGNAL_Context *sigterm;
-static struct GNUNET_SIGNAL_Context *sigint;
-static struct GNUNET_SIGNAL_Context *sighup;
-static struct GNUNET_SIGNAL_Context *sigchld;
-
-
-int
-TEH_loop_init (void)
-{
-  if (0 != pipe (reload_pipe))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                         "pipe");
-    return GNUNET_SYSERR;
-  }
-  sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
-                                           &handle_sigterm);
-  sigint = GNUNET_SIGNAL_handler_install (SIGINT,
-                                          &handle_sigint);
-  sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
-                                          &handle_sighup);
-  sigchld = GNUNET_SIGNAL_handler_install (SIGCHLD,
-                                           &handle_sigchld);
-  return GNUNET_OK;
-}
-
-
-void
-TEH_loop_done (void)
-{
-  if (NULL != sigterm)
-  {
-    GNUNET_SIGNAL_handler_uninstall (sigterm);
-    sigterm = NULL;
-  }
-  if (NULL != sigint)
-  {
-    GNUNET_SIGNAL_handler_uninstall (sigint);
-    sigint = NULL;
-  }
-  if (NULL != sighup)
-  {
-    GNUNET_SIGNAL_handler_uninstall (sighup);
-    sighup = NULL;
-  }
-  if (NULL != sigchld)
-  {
-    GNUNET_SIGNAL_handler_uninstall (sigchld);
-    sigchld = NULL;
-  }
-  if (-1 != reload_pipe[0])
-  {
-    GNUNET_break (0 == close (reload_pipe[0]));
-    GNUNET_break (0 == close (reload_pipe[1]));
-    reload_pipe[0] = reload_pipe[1] = -1;
-  }
-}
-
-
-/* end of taler-exchange-httpd_loop.c */
diff --git a/src/exchange/taler-exchange-httpd_loop.h 
b/src/exchange/taler-exchange-httpd_loop.h
deleted file mode 100644
index 700f5677..00000000
--- a/src/exchange/taler-exchange-httpd_loop.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-  This file is part of TALER
-  Copyright (C) 2014, 2015 Taler Systems SA
-
-  TALER is free software; you can redistribute it and/or modify it under the
-  terms of the GNU Affero General Public License as published by the Free 
Software
-  Foundation; either version 3, or (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
-
-  You should have received a copy of the GNU Affero General Public License 
along with
-  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file exchange/taler-exchange-httpd_loop.h
- * @brief management of our main loop
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_LOOP_H
-#define TALER_EXCHANGE_HTTPD_LOOP_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-
-/**
- * Setup our signal handlers.
- *
- * @return #GNUNET_OK on success
- */
-int
-TEH_loop_init (void);
-
-
-/**
- * Finally, tear down our signal handlers.
- */
-void
-TEH_loop_done (void);
-
-
-/**
- * Read signals from a pipe in a loop, and reload keys from disk if
- * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
- * restart if SIGHUP is received.
- *
- * @return #GNUNET_SYSERR on errors,
- *         #GNUNET_OK to terminate normally
- *         #GNUNET_NO to restart an update version of the binary
- */
-int
-TEH_loop_run (void);
-
-
-#endif
diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c 
b/src/exchange/taler-exchange-httpd_management_auditors.c
index 77e7d865..d782618f 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors.c
@@ -74,7 +74,6 @@ struct AddAuditorContext
  *
  * @param cls closure with a `struct AddAuditorContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -82,7 +81,6 @@ struct AddAuditorContext
 static enum GNUNET_DB_QueryStatus
 add_auditor (void *cls,
              struct MHD_Connection *connection,
-             struct TALER_EXCHANGEDB_Session *session,
              MHD_RESULT *mhd_ret)
 {
   struct AddAuditorContext *aac = cls;
@@ -90,7 +88,6 @@ add_auditor (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->lookup_auditor_timestamp (TEH_plugin->cls,
-                                             session,
                                              &aac->auditor_pub,
                                              &last_date);
   if (qs < 0)
@@ -116,14 +113,12 @@ add_auditor (void *cls,
   }
   if (0 == qs)
     qs = TEH_plugin->insert_auditor (TEH_plugin->cls,
-                                     session,
                                      &aac->auditor_pub,
                                      aac->auditor_url,
                                      aac->auditor_name,
                                      aac->validity_start);
   else
     qs = TEH_plugin->update_auditor (TEH_plugin->cls,
-                                     session,
                                      &aac->auditor_pub,
                                      aac->auditor_url,
                                      aac->auditor_name,
diff --git a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c 
b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
index 382b0f6b..7bf191f4 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
@@ -65,7 +65,6 @@ struct DelAuditorContext
  *
  * @param cls closure with a `struct DelAuditorContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -73,7 +72,6 @@ struct DelAuditorContext
 static enum GNUNET_DB_QueryStatus
 del_auditor (void *cls,
              struct MHD_Connection *connection,
-             struct TALER_EXCHANGEDB_Session *session,
              MHD_RESULT *mhd_ret)
 {
   struct DelAuditorContext *dac = cls;
@@ -81,7 +79,6 @@ del_auditor (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->lookup_auditor_timestamp (TEH_plugin->cls,
-                                             session,
                                              &dac->auditor_pub,
                                              &last_date);
   if (qs < 0)
@@ -114,7 +111,6 @@ del_auditor (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   qs = TEH_plugin->update_auditor (TEH_plugin->cls,
-                                   session,
                                    &dac->auditor_pub,
                                    "", /* auditor URL */
                                    "", /* auditor name */
diff --git 
a/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c 
b/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c
index 1a89652e..6519404d 100644
--- a/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c
+++ b/src/exchange/taler-exchange-httpd_management_denominations_HDP_revoke.c
@@ -70,7 +70,6 @@ TEH_handler_management_denominations_HDP_revoke (
       NULL);
   }
   qs = TEH_plugin->insert_denomination_revocation (TEH_plugin->cls,
-                                                   NULL,
                                                    h_denom_pub,
                                                    &master_sig);
   if (qs < 0)
diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c 
b/src/exchange/taler-exchange-httpd_management_post_keys.c
index 0e4eb989..311fff78 100644
--- a/src/exchange/taler-exchange-httpd_management_post_keys.c
+++ b/src/exchange/taler-exchange-httpd_management_post_keys.c
@@ -107,7 +107,6 @@ struct AddKeysContext
  *
  * @param cls closure with a `struct AddKeysContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -115,7 +114,6 @@ struct AddKeysContext
 static enum GNUNET_DB_QueryStatus
 add_keys (void *cls,
           struct MHD_Connection *connection,
-          struct TALER_EXCHANGEDB_Session *session,
           MHD_RESULT *mhd_ret)
 {
   struct AddKeysContext *akc = cls;
@@ -131,7 +129,6 @@ add_keys (void *cls,
     /* For idempotency, check if the key is already active */
     qs = TEH_plugin->lookup_denomination_key (
       TEH_plugin->cls,
-      session,
       &akc->d_sigs[i].h_denom_pub,
       &meta);
     if (qs < 0)
@@ -207,7 +204,6 @@ add_keys (void *cls,
       continue; /* skip, already known */
     qs = TEH_plugin->add_denomination_key (
       TEH_plugin->cls,
-      session,
       &akc->d_sigs[i].h_denom_pub,
       &denom_pub,
       &meta,
@@ -239,7 +235,6 @@ add_keys (void *cls,
 
     qs = TEH_plugin->lookup_signing_key (
       TEH_plugin->cls,
-      session,
       &akc->s_sigs[i].exchange_pub,
       &meta);
     if (qs < 0)
@@ -297,7 +292,6 @@ add_keys (void *cls,
       continue; /* skip, already known */
     qs = TEH_plugin->activate_signing_key (
       TEH_plugin->cls,
-      session,
       &akc->s_sigs[i].exchange_pub,
       &meta,
       &akc->s_sigs[i].master_sig);
diff --git a/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c 
b/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c
index 273c05d5..0d6317b4 100644
--- a/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c
+++ b/src/exchange/taler-exchange-httpd_management_signkey_EP_revoke.c
@@ -69,7 +69,6 @@ TEH_handler_management_signkeys_EP_revoke (
       NULL);
   }
   qs = TEH_plugin->insert_signkey_revocation (TEH_plugin->cls,
-                                              NULL,
                                               exchange_pub,
                                               &master_sig);
   if (qs < 0)
diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c 
b/src/exchange/taler-exchange-httpd_management_wire_disable.c
index 3b760ea9..17bd7273 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_disable.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_disable.c
@@ -65,7 +65,6 @@ struct DelWireContext
  *
  * @param cls closure with a `struct DelWireContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -73,7 +72,6 @@ struct DelWireContext
 static enum GNUNET_DB_QueryStatus
 del_wire (void *cls,
           struct MHD_Connection *connection,
-          struct TALER_EXCHANGEDB_Session *session,
           MHD_RESULT *mhd_ret)
 {
   struct DelWireContext *awc = cls;
@@ -81,7 +79,6 @@ del_wire (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->lookup_wire_timestamp (TEH_plugin->cls,
-                                          session,
                                           awc->payto_uri,
                                           &last_date);
   if (qs < 0)
@@ -114,7 +111,6 @@ del_wire (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   qs = TEH_plugin->update_wire (TEH_plugin->cls,
-                                session,
                                 awc->payto_uri,
                                 awc->validity_end,
                                 false);
diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c 
b/src/exchange/taler-exchange-httpd_management_wire_enable.c
index 00c95b05..4bad41b4 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_enable.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_enable.c
@@ -72,7 +72,6 @@ struct AddWireContext
  *
  * @param cls closure with a `struct AddWireContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -80,7 +79,6 @@ struct AddWireContext
 static enum GNUNET_DB_QueryStatus
 add_wire (void *cls,
           struct MHD_Connection *connection,
-          struct TALER_EXCHANGEDB_Session *session,
           MHD_RESULT *mhd_ret)
 {
   struct AddWireContext *awc = cls;
@@ -88,7 +86,6 @@ add_wire (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = TEH_plugin->lookup_wire_timestamp (TEH_plugin->cls,
-                                          session,
                                           awc->payto_uri,
                                           &last_date);
   if (qs < 0)
@@ -114,13 +111,11 @@ add_wire (void *cls,
   }
   if (0 == qs)
     qs = TEH_plugin->insert_wire (TEH_plugin->cls,
-                                  session,
                                   awc->payto_uri,
                                   awc->validity_start,
                                   &awc->master_sig_wire);
   else
     qs = TEH_plugin->update_wire (TEH_plugin->cls,
-                                  session,
                                   awc->payto_uri,
                                   awc->validity_start,
                                   true);
diff --git a/src/exchange/taler-exchange-httpd_management_wire_fees.c 
b/src/exchange/taler-exchange-httpd_management_wire_fees.c
index 5486ff33..4272a2d0 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_fees.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_fees.c
@@ -80,7 +80,6 @@ struct AddFeeContext
  *
  * @param cls closure with a `struct AddFeeContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -88,7 +87,6 @@ struct AddFeeContext
 static enum GNUNET_DB_QueryStatus
 add_fee (void *cls,
          struct MHD_Connection *connection,
-         struct TALER_EXCHANGEDB_Session *session,
          MHD_RESULT *mhd_ret)
 {
   struct AddFeeContext *afc = cls;
@@ -98,7 +96,6 @@ add_fee (void *cls,
 
   qs = TEH_plugin->lookup_wire_fee_by_time (
     TEH_plugin->cls,
-    session,
     afc->wire_method,
     afc->start_time,
     afc->end_time,
@@ -142,7 +139,6 @@ add_fee (void *cls,
 
   qs = TEH_plugin->insert_wire_fee (
     TEH_plugin->cls,
-    session,
     afc->wire_method,
     afc->start_time,
     afc->end_time,
diff --git a/src/exchange/taler-exchange-httpd_melt.c 
b/src/exchange/taler-exchange-httpd_melt.c
index 071a9c38..af0a0a63 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -170,14 +170,12 @@ struct MeltContext
  * melt operation.
  *
  * @param connection the connection to send errors to
- * @param session the database connection
  * @param[in,out] rmc melt context
  * @param[out] mhd_ret status code to return to MHD on hard error
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 refresh_check_melt (struct MHD_Connection *connection,
-                    struct TALER_EXCHANGEDB_Session *session,
                     struct MeltContext *rmc,
                     MHD_RESULT *mhd_ret)
 {
@@ -191,7 +189,6 @@ refresh_check_melt (struct MHD_Connection *connection,
   /* get historic transaction costs of this coin, including recoups as
      we might be a zombie coin */
   qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
-                                          session,
                                           &rmc->refresh_session.coin.coin_pub,
                                           GNUNET_YES,
                                           &tl);
@@ -301,7 +298,6 @@ refresh_check_melt (struct MHD_Connection *connection,
  *
  * @param cls our `struct MeltContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -309,7 +305,6 @@ refresh_check_melt (struct MHD_Connection *connection,
 static enum GNUNET_DB_QueryStatus
 melt_transaction (void *cls,
                   struct MHD_Connection *connection,
-                  struct TALER_EXCHANGEDB_Session *session,
                   MHD_RESULT *mhd_ret)
 {
   struct MeltContext *rmc = cls;
@@ -321,7 +316,6 @@ melt_transaction (void *cls,
   {
     qs = TEH_make_coin_known (&rmc->refresh_session.coin,
                               connection,
-                              session,
                               mhd_ret);
     if (qs < 0)
       return qs;
@@ -329,7 +323,6 @@ melt_transaction (void *cls,
 
   /* Check if we already created a matching refresh_session */
   qs = TEH_plugin->get_melt_index (TEH_plugin->cls,
-                                   session,
                                    &rmc->refresh_session.rc,
                                    &noreveal_index);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@@ -355,7 +348,6 @@ melt_transaction (void *cls,
 
   /* check coin has enough funds remaining on it to cover melt cost */
   qs = refresh_check_melt (connection,
-                           session,
                            rmc,
                            mhd_ret);
   if (0 > qs)
@@ -367,7 +359,6 @@ melt_transaction (void *cls,
                                 TALER_CNC_KAPPA);
   if (0 >=
       (qs = TEH_plugin->insert_melt (TEH_plugin->cls,
-                                     session,
                                      &rmc->refresh_session)))
   {
     if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
@@ -511,7 +502,6 @@ check_for_denomination_key (struct MHD_Connection 
*connection,
        revoked (those must be recouped) */
     qs = TEH_plugin->get_coin_denomination (
       TEH_plugin->cls,
-      NULL,
       &rmc->refresh_session.coin.coin_pub,
       &denom_hash);
     if (0 > qs)
diff --git a/src/exchange/taler-exchange-httpd_recoup.c 
b/src/exchange/taler-exchange-httpd_recoup.c
index 521b7562..137034a4 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -114,7 +114,6 @@ struct RecoupContext
  *
  * @param cls the `struct RecoupContext *`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status code
@@ -122,7 +121,6 @@ struct RecoupContext
 static enum GNUNET_DB_QueryStatus
 recoup_transaction (void *cls,
                     struct MHD_Connection *connection,
-                    struct TALER_EXCHANGEDB_Session *session,
                     MHD_RESULT *mhd_ret)
 {
   struct RecoupContext *pc = cls;
@@ -135,7 +133,6 @@ recoup_transaction (void *cls,
   /* make sure coin is 'known' in database */
   qs = TEH_make_coin_known (pc->coin,
                             connection,
-                            session,
                             mhd_ret);
   if (qs < 0)
     return qs;
@@ -145,7 +142,6 @@ recoup_transaction (void *cls,
   if (pc->refreshed)
   {
     qs = TEH_plugin->get_old_coin_by_h_blind (TEH_plugin->cls,
-                                              session,
                                               &pc->h_blind,
                                               &pc->target.old_coin_pub);
     if (0 > qs)
@@ -164,7 +160,6 @@ recoup_transaction (void *cls,
   else
   {
     qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
-                                             session,
                                              &pc->h_blind,
                                              &pc->target.reserve_pub);
     if (0 > qs)
@@ -194,7 +189,6 @@ recoup_transaction (void *cls,
 
   /* Calculate remaining balance, including recoups already applied. */
   qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
-                                          session,
                                           &pc->coin->coin_pub,
                                           GNUNET_YES,
                                           &tl);
@@ -270,8 +264,7 @@ recoup_transaction (void *cls,
     /* Recoup has no effect: coin fully spent! */
     enum GNUNET_DB_QueryStatus ret;
 
-    TEH_plugin->rollback (TEH_plugin->cls,
-                          session);
+    TEH_plugin->rollback (TEH_plugin->cls);
     if (GNUNET_NO == existing_recoup_found)
     {
       /* Refuse: insufficient funds for recoup */
@@ -300,7 +293,6 @@ recoup_transaction (void *cls,
   if (pc->refreshed)
   {
     qs = TEH_plugin->insert_recoup_refresh_request (TEH_plugin->cls,
-                                                    session,
                                                     pc->coin,
                                                     pc->coin_sig,
                                                     pc->coin_bks,
@@ -311,7 +303,6 @@ recoup_transaction (void *cls,
   else
   {
     qs = TEH_plugin->insert_recoup_request (TEH_plugin->cls,
-                                            session,
                                             &pc->target.reserve_pub,
                                             pc->coin,
                                             pc->coin_sig,
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c 
b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index dc4bdf0e..4ca6bd15 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -201,7 +201,6 @@ check_exists_cb (void *cls,
  *
  * @param cls closure of type `struct RevealContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -209,7 +208,6 @@ check_exists_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 refreshes_reveal_preflight (void *cls,
                             struct MHD_Connection *connection,
-                            struct TALER_EXCHANGEDB_Session *session,
                             MHD_RESULT *mhd_ret)
 {
   struct RevealContext *rctx = cls;
@@ -217,7 +215,6 @@ refreshes_reveal_preflight (void *cls,
 
   /* Try to see if we already have given an answer before. */
   qs = TEH_plugin->get_refresh_reveal (TEH_plugin->cls,
-                                       session,
                                        &rctx->rc,
                                        &check_exists_cb,
                                        rctx);
@@ -258,7 +255,6 @@ refreshes_reveal_preflight (void *cls,
  *
  * @param cls closure of type `struct RevealContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -266,7 +262,6 @@ refreshes_reveal_preflight (void *cls,
 static enum GNUNET_DB_QueryStatus
 refreshes_reveal_transaction (void *cls,
                               struct MHD_Connection *connection,
-                              struct TALER_EXCHANGEDB_Session *session,
                               MHD_RESULT *mhd_ret)
 {
   struct RevealContext *rctx = cls;
@@ -276,7 +271,6 @@ refreshes_reveal_transaction (void *cls,
   /* Obtain basic information about the refresh operation and what
      gamma we committed to. */
   qs = TEH_plugin->get_melt (TEH_plugin->cls,
-                             session,
                              &rctx->rc,
                              &melt);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -441,7 +435,6 @@ refreshes_reveal_transaction (void *cls,
  *
  * @param cls closure of type `struct RevealContext`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -449,7 +442,6 @@ refreshes_reveal_transaction (void *cls,
 static enum GNUNET_DB_QueryStatus
 refreshes_reveal_persist (void *cls,
                           struct MHD_Connection *connection,
-                          struct TALER_EXCHANGEDB_Session *session,
                           MHD_RESULT *mhd_ret)
 {
   struct RevealContext *rctx = cls;
@@ -470,7 +462,6 @@ refreshes_reveal_persist (void *cls,
       rrc->coin_sig = rctx->ev_sigs[i];
     }
     qs = TEH_plugin->insert_refresh_reveal (TEH_plugin->cls,
-                                            session,
                                             &rctx->rc,
                                             rctx->num_fresh_coins,
                                             rrcs,
@@ -621,7 +612,6 @@ resolve_refreshes_reveal_denominations (struct 
MHD_Connection *connection,
 
     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
         (qs = TEH_plugin->get_melt (TEH_plugin->cls,
-                                    NULL,
                                     &rctx->rc,
                                     &melt)))
     {
diff --git a/src/exchange/taler-exchange-httpd_refund.c 
b/src/exchange/taler-exchange-httpd_refund.c
index 2ea19b7e..73b4b251 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -94,7 +94,6 @@ reply_refund_success (struct MHD_Connection *connection,
  *
  * @param cls closure with a `const struct TALER_EXCHANGEDB_Refund *`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -102,7 +101,6 @@ reply_refund_success (struct MHD_Connection *connection,
 static enum GNUNET_DB_QueryStatus
 refund_transaction (void *cls,
                     struct MHD_Connection *connection,
-                    struct TALER_EXCHANGEDB_Session *session,
                     MHD_RESULT *mhd_ret)
 {
   const struct TALER_EXCHANGEDB_Refund *refund = cls;
@@ -118,7 +116,6 @@ refund_transaction (void *cls,
 
   tl = NULL;
   qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
-                                          session,
                                           &refund->coin.coin_pub,
                                           GNUNET_NO,
                                           &tl);
@@ -344,7 +341,6 @@ refund_transaction (void *cls,
 
   /* Finally, store new refund data */
   qs = TEH_plugin->insert_refund (TEH_plugin->cls,
-                                  session,
                                   refund);
   if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   {
@@ -407,7 +403,6 @@ verify_and_execute_refund (struct MHD_Connection 
*connection,
     enum GNUNET_DB_QueryStatus qs;
 
     qs = TEH_plugin->get_coin_denomination (TEH_plugin->cls,
-                                            NULL,
                                             &refund->coin.coin_pub,
                                             &denom_hash);
     if (0 > qs)
diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c 
b/src/exchange/taler-exchange-httpd_reserves_get.c
index 04085a0c..57ab7137 100644
--- a/src/exchange/taler-exchange-httpd_reserves_get.c
+++ b/src/exchange/taler-exchange-httpd_reserves_get.c
@@ -54,7 +54,7 @@ struct ReservePoller
    * Subscription for the database event we are
    * waiting for.
    */
-  struct TALER_EXCHANGEDB_EventHandler *eh;
+  struct GNUNET_DB_EventHandler *eh;
 
   /**
    * When will this request time out?
@@ -110,8 +110,11 @@ rp_cleanup (struct TEH_RequestContext *rc)
 {
   struct ReservePoller *rp = rc->rh_ctx;
 
+  GNUNET_assert (! rp->suspended);
   if (NULL != rp->eh)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Cancelling DB event listening\n");
     TEH_plugin->event_listen_cancel (TEH_plugin->cls,
                                      rp->eh);
     rp->eh = NULL;
@@ -153,6 +156,7 @@ db_event_cb (void *cls,
                                rp_tail,
                                rp);
   MHD_resume_connection (rp->connection);
+  TALER_MHD_daemon_trigger ();
   GNUNET_async_scope_restore (&old_scope);
 }
 
@@ -218,7 +222,6 @@ struct ReserveHistoryContext
  *
  * @param cls a `struct ReserveHistoryContext *`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!); unused
  * @return transaction status
@@ -226,7 +229,6 @@ struct ReserveHistoryContext
 static enum GNUNET_DB_QueryStatus
 reserve_history_transaction (void *cls,
                              struct MHD_Connection *connection,
-                             struct TALER_EXCHANGEDB_Session *session,
                              MHD_RESULT *mhd_ret)
 {
   struct ReserveHistoryContext *rsc = cls;
@@ -234,7 +236,6 @@ reserve_history_transaction (void *cls,
   (void) connection;
   (void) mhd_ret;
   return TEH_plugin->get_reserve_history (TEH_plugin->cls,
-                                          session,
                                           &rsc->reserve_pub,
                                           &rsc->rh);
 }
@@ -247,7 +248,7 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
   struct ReserveHistoryContext rsc;
   MHD_RESULT mhd_ret;
   struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_ZERO;
-  struct TALER_EXCHANGEDB_EventHandler *eh = NULL;
+  struct GNUNET_DB_EventHandler *eh = NULL;
 
   if (GNUNET_OK !=
       GNUNET_STRINGS_string_to_data (args[0],
@@ -288,7 +289,8 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
                                                timeout_ms);
     }
   }
-  if (! GNUNET_TIME_relative_is_zero (timeout))
+  if ( (! GNUNET_TIME_relative_is_zero (timeout)) &&
+       (NULL == rc->rh_ctx) )
   {
     struct TALER_ReserveEventP rep = {
       .header.size = htons (sizeof (rep)),
@@ -296,6 +298,8 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
       .reserve_pub = rsc.reserve_pub
     };
 
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Starting DB event listening\n");
     eh = TEH_plugin->event_listen (TEH_plugin->cls,
                                    timeout,
                                    &rep.header,
@@ -309,7 +313,12 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
                               &mhd_ret,
                               &reserve_history_transaction,
                               &rsc))
+  {
+    if (NULL != eh)
+      TEH_plugin->event_listen_cancel (TEH_plugin->cls,
+                                       eh);
     return mhd_ret;
+  }
   /* generate proper response */
   if (NULL == rsc.rh)
   {
@@ -340,6 +349,9 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
     MHD_suspend_connection (rc->connection);
     return MHD_YES;
   }
+  if (NULL != eh)
+    TEH_plugin->event_listen_cancel (TEH_plugin->cls,
+                                     eh);
   mhd_ret = reply_reserve_history_success (rc->connection,
                                            rsc.rh);
   TEH_plugin->free_reserve_history (TEH_plugin->cls,
diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c 
b/src/exchange/taler-exchange-httpd_transfers_get.c
index 9fd343a5..abf0fdbc 100644
--- a/src/exchange/taler-exchange-httpd_transfers_get.c
+++ b/src/exchange/taler-exchange-httpd_transfers_get.c
@@ -406,7 +406,6 @@ free_ctx (struct WtidTransactionContext *ctx)
  *
  * @param cls closure
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -414,7 +413,6 @@ free_ctx (struct WtidTransactionContext *ctx)
 static enum GNUNET_DB_QueryStatus
 get_transfer_deposits (void *cls,
                        struct MHD_Connection *connection,
-                       struct TALER_EXCHANGEDB_Session *session,
                        MHD_RESULT *mhd_ret)
 {
   struct WtidTransactionContext *ctx = cls;
@@ -428,7 +426,6 @@ get_transfer_deposits (void *cls,
      serialization failure */
   free_ctx (ctx);
   qs = TEH_plugin->lookup_wire_transfer (TEH_plugin->cls,
-                                         session,
                                          &ctx->wtid,
                                          &handle_deposit_data,
                                          ctx);
@@ -462,7 +459,6 @@ get_transfer_deposits (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   qs = TEH_plugin->get_wire_fee (TEH_plugin->cls,
-                                 session,
                                  ctx->wire_method,
                                  ctx->exec_time,
                                  &wire_fee_start_date,
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c 
b/src/exchange/taler-exchange-httpd_withdraw.c
index 7d10bb8e..d9cba045 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -152,7 +152,6 @@ struct WithdrawContext
  *
  * @param cls a `struct WithdrawContext *`
  * @param connection MHD request which triggered the transaction
- * @param session database session to use
  * @param[out] mhd_ret set to MHD response status for @a connection,
  *             if transaction failed (!)
  * @return transaction status
@@ -160,7 +159,6 @@ struct WithdrawContext
 static enum GNUNET_DB_QueryStatus
 withdraw_transaction (void *cls,
                       struct MHD_Connection *connection,
-                      struct TALER_EXCHANGEDB_Session *session,
                       MHD_RESULT *mhd_ret)
 {
   struct WithdrawContext *wc = cls;
@@ -175,7 +173,6 @@ withdraw_transaction (void *cls,
   wc->collectable.sig.rsa_signature = NULL;
 #endif
   qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
-                                      session,
                                       &wc->wsrd.h_coin_envelope,
                                       &wc->collectable);
   if (0 > qs)
@@ -212,7 +209,6 @@ withdraw_transaction (void *cls,
               "Trying to withdraw from reserve: %s\n",
               TALER_B2S (&r.pub));
   qs = TEH_plugin->reserves_get (TEH_plugin->cls,
-                                 session,
                                  &r);
   if (0 > qs)
   {
@@ -253,7 +249,6 @@ withdraw_transaction (void *cls,
     }
 #endif
     qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
-                                          session,
                                           &wc->wsrd.reserve_pub,
                                           &rh);
     if (NULL == rh)
@@ -300,7 +295,6 @@ withdraw_transaction (void *cls,
   wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
   wc->collectable.reserve_sig = wc->signature;
   qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls,
-                                         session,
                                          &wc->collectable);
   if (0 > qs)
   {
diff --git a/src/exchange/taler-exchange-transfer.c 
b/src/exchange/taler-exchange-transfer.c
index 56794343..d6d44eb0 100644
--- a/src/exchange/taler-exchange-transfer.c
+++ b/src/exchange/taler-exchange-transfer.c
@@ -37,11 +37,6 @@
 struct WirePrepareData
 {
 
-  /**
-   * Database session for all of our transactions.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
-
   /**
    * Wire execution handle.
    */
@@ -140,8 +135,7 @@ shutdown_task (void *cls)
       TALER_BANK_transfer_cancel (wpd->eh);
       wpd->eh = NULL;
     }
-    db_plugin->rollback (db_plugin->cls,
-                         wpd->session);
+    db_plugin->rollback (db_plugin->cls);
     GNUNET_free (wpd);
     wpd = NULL;
   }
@@ -196,16 +190,14 @@ parse_wirewatch_config (void)
 /**
  * Perform a database commit. If it fails, print a warning.
  *
- * @param session session to perform the commit for.
  * @return status of commit
  */
 static enum GNUNET_DB_QueryStatus
-commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
+commit_or_warn (void)
 {
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = db_plugin->commit (db_plugin->cls,
-                          session);
+  qs = db_plugin->commit (db_plugin->cls);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     return qs;
   GNUNET_log ((GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -245,7 +237,6 @@ wire_confirm_cb (void *cls,
                  uint64_t row_id,
                  struct GNUNET_TIME_Absolute wire_timestamp)
 {
-  struct TALER_EXCHANGEDB_Session *session = wpd->session;
   enum GNUNET_DB_QueryStatus qs;
 
   (void) cls;
@@ -256,7 +247,6 @@ wire_confirm_cb (void *cls,
   {
   case MHD_HTTP_OK:
     qs = db_plugin->wire_prepare_data_mark_finished (db_plugin->cls,
-                                                     session,
                                                      wpd->row_id);
     /* continued below */
     break;
@@ -267,7 +257,6 @@ wire_confirm_cb (void *cls,
                 http_status_code,
                 ec);
     qs = db_plugin->wire_prepare_data_mark_failed (db_plugin->cls,
-                                                   session,
                                                    wpd->row_id);
     /* continued below */
     break;
@@ -276,8 +265,7 @@ wire_confirm_cb (void *cls,
                 "Wire transaction failed: %u/%d\n",
                 http_status_code,
                 ec);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     GNUNET_free (wpd);
@@ -287,8 +275,7 @@ wire_confirm_cb (void *cls,
   if (0 >= qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     {
       /* try again */
@@ -307,7 +294,7 @@ wire_confirm_cb (void *cls,
   }
   GNUNET_free (wpd);
   wpd = NULL;
-  switch (commit_or_warn (session))
+  switch (commit_or_warn ())
   {
   case GNUNET_DB_STATUS_SOFT_ERROR:
     /* try again */
@@ -362,8 +349,7 @@ wire_prepare_cb (void *cls,
        (NULL == buf) )
   {
     GNUNET_break (0);
-    db_plugin->rollback (db_plugin->cls,
-                         wpd->session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     goto cleanup;
   }
@@ -377,8 +363,7 @@ wire_prepare_cb (void *cls,
     /* Should really never happen here, as when we get
        here the wire account should be in the cache. */
     GNUNET_break (0);
-    db_plugin->rollback (db_plugin->cls,
-                         wpd->session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_NOTCONFIGURED;
     goto cleanup;
   }
@@ -392,8 +377,7 @@ wire_prepare_cb (void *cls,
   if (NULL == wpd->eh)
   {
     GNUNET_break (0); /* Irrecoverable */
-    db_plugin->rollback (db_plugin->cls,
-                         wpd->session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     goto cleanup;
   }
@@ -415,23 +399,22 @@ static void
 run_transfers (void *cls)
 {
   enum GNUNET_DB_QueryStatus qs;
-  struct TALER_EXCHANGEDB_Session *session;
 
   (void) cls;
   task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Checking for pending wire transfers\n");
-  if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
+  if (GNUNET_SYSERR ==
+      db_plugin->preflight (db_plugin->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to obtain database session!\n");
+                "Failed to obtain database connection!\n");
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
   if (GNUNET_OK !=
       db_plugin->start (db_plugin->cls,
-                        session,
                         "aggregator run transfer"))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -441,15 +424,12 @@ run_transfers (void *cls)
     return;
   }
   wpd = GNUNET_new (struct WirePrepareData);
-  wpd->session = session;
   qs = db_plugin->wire_prepare_data_get (db_plugin->cls,
-                                         session,
                                          &wire_prepare_cb,
                                          NULL);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
     return;  /* continued via continuation set in #wire_prepare_cb() */
-  db_plugin->rollback (db_plugin->cls,
-                       session);
+  db_plugin->rollback (db_plugin->cls);
   GNUNET_free (wpd);
   wpd = NULL;
   switch (qs)
diff --git a/src/exchange/taler-exchange-wirewatch.c 
b/src/exchange/taler-exchange-wirewatch.c
index 2993999a..fb1fde31 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -62,11 +62,6 @@ struct WireAccount
    */
   const struct TALER_EXCHANGEDB_AccountInfo *ai;
 
-  /**
-   * Database session we are using for the current transaction.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
-
   /**
    * Active request for history.
    */
@@ -355,8 +350,7 @@ find_transfers (void *cls);
 static void
 handle_soft_error (struct WireAccount *wa)
 {
-  db_plugin->rollback (db_plugin->cls,
-                       wa->session);
+  db_plugin->rollback (db_plugin->cls);
   if (1 < wa->batch_size)
   {
     wa->batch_thresh = wa->batch_size;
@@ -386,7 +380,6 @@ do_commit (struct WireAccount *wa)
   {
     /* shard is complete, mark this as well */
     qs = db_plugin->complete_shard (db_plugin->cls,
-                                    wa->session,
                                     wa->job_name,
                                     wa->shard_start,
                                     wa->shard_end);
@@ -394,8 +387,7 @@ do_commit (struct WireAccount *wa)
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      db_plugin->rollback (db_plugin->cls,
-                           wa->session);
+      db_plugin->rollback (db_plugin->cls);
       GNUNET_SCHEDULER_shutdown ();
       return;
     case GNUNET_DB_STATUS_SOFT_ERROR:
@@ -413,8 +405,7 @@ do_commit (struct WireAccount *wa)
       break;
     }
   }
-  qs = db_plugin->commit (db_plugin->cls,
-                          wa->session);
+  qs = db_plugin->commit (db_plugin->cls);
   switch (qs)
   {
   case GNUNET_DB_STATUS_HARD_ERROR:
@@ -432,7 +423,6 @@ do_commit (struct WireAccount *wa)
   }
   /* transaction success, update #last_row_off */
   wa->batch_start = wa->latest_row_off;
-  wa->session = NULL;     /* should not be needed */
   if (wa->batch_size < MAXIMUM_BATCH_SIZE)
   {
     int delta;
@@ -492,7 +482,6 @@ history_cb (void *cls,
             const json_t *json)
 {
   struct WireAccount *wa = cls;
-  struct TALER_EXCHANGEDB_Session *session = wa->session;
   enum GNUNET_DB_QueryStatus qs;
 
   (void) json;
@@ -518,8 +507,7 @@ history_cb (void *cls,
                 "Serial ID %llu not monotonic (got %llu before). Failing!\n",
                 (unsigned long long) serial_id,
                 (unsigned long long) wa->latest_row_off);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     GNUNET_SCHEDULER_shutdown ();
     wa->hh = NULL;
     return GNUNET_SYSERR;
@@ -547,7 +535,6 @@ history_cb (void *cls,
      (Note: this may require changing both the
      plugin API as well as modifying how this function is called.) */
   qs = db_plugin->reserves_in_insert (db_plugin->cls,
-                                      session,
                                       &details->reserve_pub,
                                       &details->amount,
                                       details->execution_date,
@@ -558,8 +545,7 @@ history_cb (void *cls,
   {
   case GNUNET_DB_STATUS_HARD_ERROR:
     GNUNET_break (0);
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     GNUNET_SCHEDULER_shutdown ();
     wa->hh = NULL;
     return GNUNET_SYSERR;
@@ -590,23 +576,22 @@ history_cb (void *cls,
 static void
 find_transfers (void *cls)
 {
-  struct TALER_EXCHANGEDB_Session *session;
   enum GNUNET_DB_QueryStatus qs;
   unsigned int limit;
 
   (void) cls;
   task = NULL;
-  if (NULL == (session = db_plugin->get_session (db_plugin->cls)))
+  if (GNUNET_SYSERR ==
+      db_plugin->preflight (db_plugin->cls))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to obtain database session!\n");
+                "Failed to obtain database connection!\n");
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
   wa_pos->delay = true;
   wa_pos->current_batch_size = 0; /* reset counter */
-  wa_pos->session = session;
   if (wa_pos->shard_end <= wa_pos->batch_start)
   {
     uint64_t start;
@@ -662,7 +647,6 @@ find_transfers (void *cls)
   }
   if (GNUNET_OK !=
       db_plugin->start_read_committed (db_plugin->cls,
-                                       session,
                                        "wirewatch check for incoming wire 
transfers"))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -689,8 +673,7 @@ find_transfers (void *cls)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failed to start request for account history!\n");
-    db_plugin->rollback (db_plugin->cls,
-                         session);
+    db_plugin->rollback (db_plugin->cls);
     global_ret = EXIT_FAILURE;
     GNUNET_SCHEDULER_shutdown ();
     return;
diff --git a/src/exchange/test_taler_exchange_httpd_restart.sh 
b/src/exchange/test_taler_exchange_httpd_restart.sh
deleted file mode 100755
index 26a315bf..00000000
--- a/src/exchange/test_taler_exchange_httpd_restart.sh
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/bin/bash
-#
-# This file is part of TALER
-# Copyright (C) 2020 Taler Systems SA
-#
-#  TALER is free software; you can redistribute it and/or modify it under the
-#  terms of the GNU Affero General Public License as published by the Free 
Software
-#  Foundation; either version 3, or (at your option) any later version.
-#
-#  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
-#  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
-#
-#  You should have received a copy of the GNU Affero General Public License 
along with
-#  TALER; see the file COPYING.  If not, If not, see 
<http://www.gnu.org/licenses/>
-#
-#
-# This script launches an exchange (binding to a UNIX domain socket) and then
-# restarts it in various ways (SIGHUP to re-read configuration, and SIGUSR1 to
-# re-spawn a new binary).  Basically, the goal is to make sure that the HTTP
-# server survives these less common operations.
-#
-#
-set -eu
-
-# Exit, with status code "skip" (no 'real' failure)
-function exit_skip() {
-    echo $1
-    exit 77
-}
-
-# Exit, with error message (hard failure)
-function exit_fail() {
-    echo $1
-    kill `jobs -p` >/dev/null 2>/dev/null || true
-    wait
-    exit 1
-}
-
-echo -n "Testing for curl"
-curl --version >/dev/null </dev/null || exit_skip " MISSING"
-echo " FOUND"
-
-
-# Clear environment from variables that override config.
-unset XDG_DATA_HOME
-unset XDG_CONFIG_HOME
-#
-echo -n "Launching exchange ..."
-PREFIX=
-# Uncomment this line to run with valgrind...
-# PREFIX="valgrind --trace-children=yes --leak-check=yes --track-fds=yes 
--error-exitcode=1 --log-file=valgrind.%p"
-
-CONFIG=test_taler_exchange_unix.conf
-
-# Setup database
-taler-exchange-dbinit -c $CONFIG &> /dev/null
-# Run Exchange HTTPD (in background)
-$PREFIX taler-exchange-httpd -c $CONFIG 2> test-exchange.log &
-
-# Where should we be bound to?
-UNIXPATH=`taler-config -c $CONFIG -s exchange -f -o UNIXPATH`
-
-# Give HTTP time to start
-
-for n in `seq 1 100`
-do
-    echo -n "."
-    sleep 0.1
-    OK=1
-    curl --unix-socket "${UNIXPATH}" "http://ignored/"; >/dev/null 2> /dev/null 
&& break
-    OK=0
-done
-if [ 1 != $OK ]
-then
-    exit_fail "Failed to launch exchange"
-fi
-echo " DONE"
-
-# Finally run test...
-echo -n "Restarting program ..."
-kill -SIGHUP $!
-sleep 1
-curl --unix-socket "${UNIXPATH}" "http://ignored/"; >/dev/null 2> /dev/null || 
exit_fail "SIGHUP killed HTTP service"
-echo " DONE"
-
-echo -n "Waiting for parent to die ..."
-wait $!
-echo " DONE"
-
-echo -n "Testing child still alive ..."
-curl --unix-socket "${UNIXPATH}" "http://ignored/"; >/dev/null 2> /dev/null || 
exit_fail "SIGHUP killed HTTP service"
-echo " DONE"
-
-
-echo -n "Killing grandchild ..."
-CPID=`ps x | grep taler-exchange-httpd | grep -v grep | awk '{print $1}'`
-kill -TERM $CPID
-while true
-do
-    ps x | grep -v grep | grep taler-exchange-httpd > /dev/null || break
-    sleep 0.1
-done
-echo " DONE"
-
-# Return status code from exchange for this script
-exit 0
diff --git a/src/exchangedb/irbt_callbacks.c b/src/exchangedb/irbt_callbacks.c
index e0e19ef0..63d64f31 100644
--- a/src/exchangedb/irbt_callbacks.c
+++ b/src/exchangedb/irbt_callbacks.c
@@ -29,12 +29,10 @@
  * Function called with denominations records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_denominations (struct PostgresClosure *pg,
-                             struct TALER_EXCHANGEDB_Session *session,
                              const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_HashCode denom_hash;
@@ -65,12 +63,11 @@ irbt_cb_table_denominations (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
   GNUNET_CRYPTO_rsa_public_key_hash (
     td->details.denominations.denom_pub.rsa_public_key,
     &denom_hash);
 
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_denominations",
                                              params);
 }
@@ -80,14 +77,12 @@ irbt_cb_table_denominations (struct PostgresClosure *pg,
  * Function called with denomination_revocations records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
-irbt_cb_table_denomination_revocations (struct PostgresClosure *pg,
-                                        struct TALER_EXCHANGEDB_Session 
*session,
-                                        const struct
-                                        TALER_EXCHANGEDB_TableData *td)
+irbt_cb_table_denomination_revocations (
+  struct PostgresClosure *pg,
+  const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&td->serial),
@@ -98,8 +93,7 @@ irbt_cb_table_denomination_revocations (struct 
PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_denomination_revocations",
                                              params);
 }
@@ -109,12 +103,10 @@ irbt_cb_table_denomination_revocations (struct 
PostgresClosure *pg,
  * Function called with reserves records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_reserves (struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -127,8 +119,7 @@ irbt_cb_table_reserves (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_reserves",
                                              params);
 }
@@ -138,12 +129,10 @@ irbt_cb_table_reserves (struct PostgresClosure *pg,
  * Function called with reserves_in records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_reserves_in (struct PostgresClosure *pg,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -160,8 +149,7 @@ irbt_cb_table_reserves_in (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_reserves_in",
                                              params);
 }
@@ -171,12 +159,10 @@ irbt_cb_table_reserves_in (struct PostgresClosure *pg,
  * Function called with reserves_close records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_reserves_close (struct PostgresClosure *pg,
-                              struct TALER_EXCHANGEDB_Session *session,
                               const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -191,8 +177,7 @@ irbt_cb_table_reserves_close (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_reserves_close",
                                              params);
 }
@@ -202,12 +187,10 @@ irbt_cb_table_reserves_close (struct PostgresClosure *pg,
  * Function called with reserves_out records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_reserves_out (struct PostgresClosure *pg,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -226,8 +209,7 @@ irbt_cb_table_reserves_out (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_reserves_out",
                                              params);
 }
@@ -237,12 +219,10 @@ irbt_cb_table_reserves_out (struct PostgresClosure *pg,
  * Function called with auditors records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_auditors (struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td)
 {
   uint8_t is_active = td->details.auditors.is_active ? 1 : 0;
@@ -256,8 +236,7 @@ irbt_cb_table_auditors (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_auditors",
                                              params);
 }
@@ -267,12 +246,10 @@ irbt_cb_table_auditors (struct PostgresClosure *pg,
  * Function called with auditor_denom_sigs records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_auditor_denom_sigs (struct PostgresClosure *pg,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -285,8 +262,7 @@ irbt_cb_table_auditor_denom_sigs (struct PostgresClosure 
*pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_auditor_denom_sigs",
                                              params);
 }
@@ -296,12 +272,10 @@ irbt_cb_table_auditor_denom_sigs (struct PostgresClosure 
*pg,
  * Function called with exchange_sign_keys records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_exchange_sign_keys (struct PostgresClosure *pg,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -319,8 +293,7 @@ irbt_cb_table_exchange_sign_keys (struct PostgresClosure 
*pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_exchange_sign_keys",
                                              params);
 }
@@ -330,12 +303,10 @@ irbt_cb_table_exchange_sign_keys (struct PostgresClosure 
*pg,
  * Function called with signkey_revocations records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_signkey_revocations (struct PostgresClosure *pg,
-                                   struct TALER_EXCHANGEDB_Session *session,
                                    const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -346,8 +317,7 @@ irbt_cb_table_signkey_revocations (struct PostgresClosure 
*pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_signkey_revocations",
                                              params);
 }
@@ -357,12 +327,10 @@ irbt_cb_table_signkey_revocations (struct PostgresClosure 
*pg,
  * Function called with known_coins records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_known_coins (struct PostgresClosure *pg,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -375,8 +343,7 @@ irbt_cb_table_known_coins (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_known_coins",
                                              params);
 }
@@ -386,12 +353,10 @@ irbt_cb_table_known_coins (struct PostgresClosure *pg,
  * Function called with refresh_commitments records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_refresh_commitments (struct PostgresClosure *pg,
-                                   struct TALER_EXCHANGEDB_Session *session,
                                    const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -408,8 +373,7 @@ irbt_cb_table_refresh_commitments (struct PostgresClosure 
*pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_refresh_commitments",
                                              params);
 }
@@ -419,14 +383,12 @@ irbt_cb_table_refresh_commitments (struct PostgresClosure 
*pg,
  * Function called with refresh_revealed_coins records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
-irbt_cb_table_refresh_revealed_coins (struct PostgresClosure *pg,
-                                      struct TALER_EXCHANGEDB_Session *session,
-                                      const struct
-                                      TALER_EXCHANGEDB_TableData *td)
+irbt_cb_table_refresh_revealed_coins (
+  struct PostgresClosure *pg,
+  const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_HashCode h_coin_ev;
   struct GNUNET_PQ_QueryParam params[] = {
@@ -449,11 +411,10 @@ irbt_cb_table_refresh_revealed_coins (struct 
PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
   GNUNET_CRYPTO_hash (td->details.refresh_revealed_coins.coin_ev,
                       td->details.refresh_revealed_coins.coin_ev_size,
                       &h_coin_ev);
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_refresh_revealed_coins",
                                              params);
 }
@@ -463,13 +424,11 @@ irbt_cb_table_refresh_revealed_coins (struct 
PostgresClosure *pg,
  * Function called with refresh_transfer_keys records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_refresh_transfer_keys (
   struct PostgresClosure *pg,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -485,8 +444,7 @@ irbt_cb_table_refresh_transfer_keys (
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_refresh_transfer_keys",
                                              params);
 }
@@ -496,12 +454,10 @@ irbt_cb_table_refresh_transfer_keys (
  * Function called with deposits records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_deposits (struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td)
 {
   uint8_t tiny = td->details.deposits.tiny ? 1 : 0;
@@ -527,10 +483,9 @@ irbt_cb_table_deposits (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
   TALER_JSON_merchant_wire_signature_hash (td->details.deposits.wire,
                                            &h_wire);
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_deposits",
                                              params);
 }
@@ -540,12 +495,10 @@ irbt_cb_table_deposits (struct PostgresClosure *pg,
  * Function called with refunds records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_refunds (struct PostgresClosure *pg,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -557,8 +510,7 @@ irbt_cb_table_refunds (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_refunds",
                                              params);
 }
@@ -568,12 +520,10 @@ irbt_cb_table_refunds (struct PostgresClosure *pg,
  * Function called with wire_out records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_wire_out (struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -587,8 +537,7 @@ irbt_cb_table_wire_out (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_wire_out",
                                              params);
 }
@@ -598,12 +547,10 @@ irbt_cb_table_wire_out (struct PostgresClosure *pg,
  * Function called with aggregation_tracking records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_aggregation_tracking (struct PostgresClosure *pg,
-                                    struct TALER_EXCHANGEDB_Session *session,
                                     const struct TALER_EXCHANGEDB_TableData 
*td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -615,8 +562,7 @@ irbt_cb_table_aggregation_tracking (struct PostgresClosure 
*pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_aggregation_tracking",
                                              params);
 }
@@ -626,12 +572,10 @@ irbt_cb_table_aggregation_tracking (struct 
PostgresClosure *pg,
  * Function called with wire_fee records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_wire_fee (struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -645,8 +589,7 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_wire_fee",
                                              params);
 }
@@ -656,12 +599,10 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg,
  * Function called with recoup records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_recoup (struct PostgresClosure *pg,
-                      struct TALER_EXCHANGEDB_Session *session,
                       const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -675,8 +616,7 @@ irbt_cb_table_recoup (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_into_table_recoup",
                                              params);
 }
@@ -686,12 +626,10 @@ irbt_cb_table_recoup (struct PostgresClosure *pg,
  * Function called with recoup_refresh records to insert into table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  */
 static enum GNUNET_DB_QueryStatus
 irbt_cb_table_recoup_refresh (struct PostgresClosure *pg,
-                              struct TALER_EXCHANGEDB_Session *session,
                               const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct GNUNET_PQ_QueryParam params[] = {
@@ -706,8 +644,7 @@ irbt_cb_table_recoup_refresh (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_end
   };
 
-  (void) pg;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              
"insert_into_table_recoup_refresh",
                                              params);
 }
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 8b805f6b..95ea6a4b 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -87,62 +87,6 @@
 } while (0)
 
 
-/**
- * Handler for a database session (per-thread, for transactions).
- */
-struct TALER_EXCHANGEDB_Session
-{
-  /**
-   * Postgres connection handle.
-   */
-  struct GNUNET_PQ_Context *conn;
-
-  /**
-   * Name of the current transaction, for debugging.
-   */
-  const char *transaction_name;
-
-  /**
-   * Did we initialize the prepared statements
-   * for this session?
-   */
-  bool init;
-};
-
-
-/**
- * Event registration record.
- */
-struct TALER_EXCHANGEDB_EventHandler
-{
-  /**
-   * Underlying GNUnet event handler.
-   */
-  struct GNUNET_DB_EventHandler *geh;
-
-  /**
-   * Entry in the heap.
-   */
-  struct GNUNET_CONTAINER_HeapNode *hn;
-
-  /**
-   * Our timeout.
-   */
-  struct GNUNET_TIME_Absolute timeout;
-
-  /**
-   * Callback to invoke (on @e timeout).
-   */
-  GNUNET_DB_EventCallback cb;
-
-  /**
-   * Closure for @e cb.
-   */
-  void *cb_cls;
-
-};
-
-
 /**
  * Type of the "cls" argument given to each of the functions in
  * our API.
@@ -150,12 +94,6 @@ struct TALER_EXCHANGEDB_EventHandler
 struct PostgresClosure
 {
 
-  /**
-   * Thread-local database connection.
-   * Contains a pointer to `struct GNUNET_PQ_Context` or NULL.
-   */
-  pthread_key_t db_conn_threadlocal;
-
   /**
    * Our configuration.
    */
@@ -166,12 +104,6 @@ struct PostgresClosure
    */
   char *sql_dir;
 
-  /**
-   * Heap of `struct TALER_EXCHANGEDB_EventHandler`
-   * by timeout.
-   */
-  struct GNUNET_CONTAINER_Heap *event_heap;
-
   /**
    * After how long should idle reserves be closed?
    */
@@ -189,25 +121,14 @@ struct PostgresClosure
   char *currency;
 
   /**
-   * Session to be used if the thread is @e main_self.
-   */
-  struct TALER_EXCHANGEDB_Session *main_session;
-
-  /**
-   * Handle for the main() thread of the program.
-   */
-  pthread_t main_self;
-
-  /**
-   * Thread responsible for processing database event
-   * notifications.
+   * Postgres connection handle.
    */
-  pthread_t event_thread;
+  struct GNUNET_PQ_Context *conn;
 
   /**
-   * Lock for @e listener_count access.
+   * Name of the current transaction, for debugging.
    */
-  pthread_mutex_t event_lock;
+  const char *transaction_name;
 
   /**
    * Number of registered listerners. @e event_thread
@@ -216,15 +137,11 @@ struct PostgresClosure
   uint64_t listener_count;
 
   /**
-   * Additional FD to signal the @e event_thread
-   * (used to stop it).
+   * Did we initialize the prepared statements
+   * for this session?
    */
-  int event_fd;
+  bool init;
 
-  /**
-   * Current Postges socket we watch on for notifications.
-   */
-  int pg_sock;
 };
 
 
@@ -237,10 +154,10 @@ struct PostgresClosure
 static int
 postgres_drop_tables (void *cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_Context *conn;
 
-  conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+  conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
                                      "exchangedb-postgres",
                                      "drop",
                                      NULL,
@@ -261,10 +178,10 @@ postgres_drop_tables (void *cls)
 static int
 postgres_create_tables (void *cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_Context *conn;
 
-  conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+  conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
                                      "exchangedb-postgres",
                                      "exchange-",
                                      NULL,
@@ -276,27 +193,6 @@ postgres_create_tables (void *cls)
 }
 
 
-/**
- * Close thread-local database connection when a thread is destroyed.
- *
- * @param cls closure we get from pthreads (the db handle)
- */
-static void
-db_conn_destroy (void *cls)
-{
-  struct TALER_EXCHANGEDB_Session *session = cls;
-  struct GNUNET_PQ_Context *db_conn;
-
-  if (NULL == session)
-    return;
-  db_conn = session->conn;
-  session->conn = NULL;
-  if (NULL != db_conn)
-    GNUNET_PQ_disconnect (db_conn);
-  GNUNET_free (session);
-}
-
-
 /**
  * Initialize prepared statements for @a sess.
  *
@@ -304,7 +200,7 @@ db_conn_destroy (void *cls)
  * @return #GNUNET_OK on success
  */
 static enum GNUNET_GenericReturnValue
-init_session (struct TALER_EXCHANGEDB_Session *sess)
+prepare_statements (struct PostgresClosure *pg)
 {
   enum GNUNET_GenericReturnValue ret;
   struct GNUNET_PQ_PreparedStatement ps[] = {
@@ -2541,41 +2437,27 @@ init_session (struct TALER_EXCHANGEDB_Session *sess)
     GNUNET_PQ_PREPARED_STATEMENT_END
   };
 
-  ret = GNUNET_PQ_prepare_statements (sess->conn,
+  ret = GNUNET_PQ_prepare_statements (pg->conn,
                                       ps);
   if (GNUNET_OK != ret)
     return ret;
-  sess->init = true;
+  pg->init = true;
   return GNUNET_OK;
 }
 
 
 /**
- * Get the thread-local database-handle.
- * Connect to the db if the connection does not exist yet.
+ * Connect to the database if the connection does not exist yet.
  *
- * @param pc the plugin-specific state
+ * @param pg the plugin-specific state
  * @param skip_prepare true if we should skip prepared statement setup
- * @return the database connection, or NULL on error
+ * @return #GNUNET_OK on success
  */
-static struct TALER_EXCHANGEDB_Session *
-internal_get_session (struct PostgresClosure *pc,
-                      bool skip_prepare)
+static enum GNUNET_GenericReturnValue
+internal_setup (struct PostgresClosure *pg,
+                bool skip_prepare)
 {
-  struct GNUNET_PQ_Context *db_conn;
-  struct TALER_EXCHANGEDB_Session *session;
-
-  if (pthread_equal (pc->main_self,
-                     pthread_self ()))
-    session = pc->main_session;
-  else
-    session = pthread_getspecific (pc->db_conn_threadlocal);
-  if (NULL != session)
-  {
-    if (NULL == session->transaction_name)
-      GNUNET_PQ_reconnect_if_down (session->conn);
-    return session;
-  }
+  if (NULL == pg->conn)
   {
 #if AUTO_EXPLAIN
     /* Enable verbose logging to see where queries do not
@@ -2596,123 +2478,108 @@ internal_get_session (struct PostgresClosure *pc,
 #else
     struct GNUNET_PQ_ExecuteStatement *es = NULL;
 #endif
+    struct GNUNET_PQ_Context *db_conn;
 
-    db_conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
+    db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
                                           "exchangedb-postgres",
                                           NULL,
                                           es,
                                           NULL);
+    if (NULL == db_conn)
+      return GNUNET_SYSERR;
+    pg->conn = db_conn;
   }
-  if (NULL == db_conn)
-    return NULL;
-  session = GNUNET_new (struct TALER_EXCHANGEDB_Session);
-  session->conn = db_conn;
-  if ( (! skip_prepare) &&
-       (GNUNET_OK !=
-        init_session (session)) )
-  {
-    GNUNET_break (0);
-    GNUNET_PQ_disconnect (db_conn);
-    GNUNET_free (session);
-    return NULL;
-  }
-  if (pthread_equal (pc->main_self,
-                     pthread_self ()))
-  {
-    pc->main_session = session;
-  }
-  else
-  {
-    if (0 != pthread_setspecific (pc->db_conn_threadlocal,
-                                  session))
-    {
-      GNUNET_break (0);
-      GNUNET_PQ_disconnect (db_conn);
-      GNUNET_free (session);
-      return NULL;
-    }
-  }
-  return session;
+  if (NULL == pg->transaction_name)
+    GNUNET_PQ_reconnect_if_down (pg->conn);
+  if (pg->init)
+    return GNUNET_OK;
+  if (skip_prepare)
+    return GNUNET_OK;
+  return prepare_statements (pg);
 }
 
 
 /**
- * Get the thread-local database-handle.
- * Connect to the db if the connection does not exist yet.
+ * Do a pre-flight check that we are not in an uncommitted transaction.
+ * If we are, try to commit the previous transaction and output a warning.
+ * Does not return anything, as we will continue regardless of the outcome.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return the database connection, or NULL on error
+ * @return #GNUNET_OK if everything is fine
+ *         #GNUNET_NO if a transaction was rolled back
+ *         #GNUNET_SYSERR on hard errors
  */
-static struct TALER_EXCHANGEDB_Session *
-postgres_get_session (void *cls)
+static enum GNUNET_GenericReturnValue
+postgres_preflight (void *cls)
 {
-  struct PostgresClosure *pc = cls;
-  struct TALER_EXCHANGEDB_Session *sess;
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
 
-  sess = internal_get_session (pc,
-                               false);
-  if (! sess->init)
+  if (! pg->init)
   {
     if (GNUNET_OK !=
-        init_session (sess))
-    {
-      GNUNET_break (0);
-      return NULL;
-    }
+        internal_setup (pg,
+                        false))
+      return GNUNET_SYSERR;
   }
-  return sess;
+  if (NULL == pg->transaction_name)
+    return GNUNET_OK; /* all good */
+  if (GNUNET_OK ==
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check rolled back transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check failed to rollback transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  pg->transaction_name = NULL;
+  return GNUNET_NO;
 }
 
 
-/**
- * Do a pre-flight check that we are not in an uncommitted transaction.
- * If we are, try to commit the previous transaction and output a warning.
- * Does not return anything, as we will continue regardless of the outcome.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
- */
-static void
-postgres_preflight (void *cls,
-                    struct TALER_EXCHANGEDB_Session *session);
-
 /**
  * Start a transaction.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
  * @param name unique name identifying the transaction (for debugging)
  *             must point to a constant
  * @return #GNUNET_OK on success
  */
 static int
 postgres_start (void *cls,
-                struct TALER_EXCHANGEDB_Session *session,
                 const char *name)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
     GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
-  (void) cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Starting transaction named: %s\n",
-              name);
-  postgres_preflight (cls,
-                      session);
+  if (GNUNET_SYSERR ==
+      postgres_preflight (pg))
+    return GNUNET_SYSERR;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Starting transaction on %p\n",
-              session->conn);
+              "Starting transaction named %s on %p\n",
+              name,
+              pg->conn);
   if (GNUNET_OK !=
-      GNUNET_PQ_exec_statements (session->conn,
+      GNUNET_PQ_exec_statements (pg->conn,
                                  es))
   {
     TALER_LOG_ERROR ("Failed to start transaction\n");
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  session->transaction_name = name;
+  pg->transaction_name = name;
   return GNUNET_OK;
 }
 
@@ -2721,39 +2588,36 @@ postgres_start (void *cls,
  * Start a READ COMMITTED transaction.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
  * @param name unique name identifying the transaction (for debugging)
  *             must point to a constant
  * @return #GNUNET_OK on success
  */
 static int
 postgres_start_read_committed (void *cls,
-                               struct TALER_EXCHANGEDB_Session *session,
                                const char *name)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
     GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ 
COMMITTED"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
-  (void) cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Starting transaction named: %s\n",
-              name);
-  postgres_preflight (cls,
-                      session);
+  if (GNUNET_SYSERR ==
+      postgres_preflight (pg))
+    return GNUNET_SYSERR;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Starting transaction on %p\n",
-              session->conn);
+              "Starting transaction named %s on %p\n",
+              name,
+              pg->conn);
   if (GNUNET_OK !=
-      GNUNET_PQ_exec_statements (session->conn,
+      GNUNET_PQ_exec_statements (pg->conn,
                                  es))
   {
     TALER_LOG_ERROR ("Failed to start transaction\n");
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  session->transaction_name = name;
+  pg->transaction_name = name;
   return GNUNET_OK;
 }
 
@@ -2762,25 +2626,23 @@ postgres_start_read_committed (void *cls,
  * Roll back the current transaction of a database connection.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
  */
 static void
-postgres_rollback (void *cls,
-                   struct TALER_EXCHANGEDB_Session *session)
+postgres_rollback (void *cls)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
     GNUNET_PQ_make_execute ("ROLLBACK"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
-  (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Rolling back transaction on %p\n",
-              session->conn);
+              pg->conn);
   GNUNET_break (GNUNET_OK ==
-                GNUNET_PQ_exec_statements (session->conn,
+                GNUNET_PQ_exec_statements (pg->conn,
                                            es));
-  session->transaction_name = NULL;
+  pg->transaction_name = NULL;
 }
 
 
@@ -2788,179 +2650,25 @@ postgres_rollback (void *cls,
  * Commit the current transaction of a database connection.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
  * @return final transaction status
  */
 static enum GNUNET_DB_QueryStatus
-postgres_commit (void *cls,
-                 struct TALER_EXCHANGEDB_Session *session)
+postgres_commit (void *cls)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                            "do_commit",
                                            params);
-  session->transaction_name = NULL;
+  pg->transaction_name = NULL;
   return qs;
 }
 
 
-/**
- * Do a pre-flight check that we are not in an uncommitted transaction.
- * If we are, try to commit the previous transaction and output a warning.
- * Does not return anything, as we will continue regardless of the outcome.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
- */
-static void
-postgres_preflight (void *cls,
-                    struct TALER_EXCHANGEDB_Session *session)
-{
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("ROLLBACK"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-
-  (void) cls;
-  if (NULL == session)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  if (NULL == session->transaction_name)
-    return; /* all good */
-  if (GNUNET_OK ==
-      GNUNET_PQ_exec_statements (session->conn,
-                                 es))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check rolled back transaction `%s'!\n",
-                session->transaction_name);
-  }
-  else
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check failed to rollback transaction `%s'!\n",
-                session->transaction_name);
-  }
-  session->transaction_name = NULL;
-}
-
-
-/**
- * Main function of the thread that processes events.
- *
- * @param cls a `struct PostgresClosure *`
- */
-static void *
-handle_events (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct pollfd pfds[] = {
-    {
-      .fd = pg->event_fd,
-      .events = POLLIN
-    },
-    {
-      .fd = pg->pg_sock,
-      .events = POLLIN
-    }
-  };
-  nfds_t nfds = (-1 == pg->pg_sock) ? 1 : 2;
-  struct TALER_EXCHANGEDB_EventHandler *r;
-
-  GNUNET_assert (0 ==
-                 pthread_mutex_lock (&pg->event_lock));
-  while (0 != pg->listener_count)
-  {
-    int ret;
-    int timeout = -1; /* no timeout */
-
-    GNUNET_assert (0 ==
-                   pthread_mutex_unlock (&pg->event_lock));
-    while (1)
-    {
-      r = GNUNET_CONTAINER_heap_peek (pg->event_heap);
-      if (NULL == r)
-        break;
-      if (GNUNET_TIME_absolute_is_future (r->timeout))
-        break;
-      GNUNET_assert (r ==
-                     GNUNET_CONTAINER_heap_remove_root (pg->event_heap));
-      r->hn = NULL;
-      r->cb (r->cb_cls,
-             NULL,
-             0);
-    }
-    if (NULL != r)
-    {
-      struct GNUNET_TIME_Relative rem;
-
-      rem = GNUNET_TIME_absolute_get_remaining (r->timeout);
-      timeout = rem.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
-    }
-    ret = poll (pfds,
-                nfds,
-                timeout);
-    if (-1 == ret)
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                           "poll");
-    for (int i = 0; i<ret; i++)
-    {
-      if ( (pg->event_fd == pfds[i].fd) &&
-           (0 != (POLLIN & pfds[i].revents)) )
-      {
-        /* consume signal */
-        uint64_t val;
-
-        GNUNET_break (sizeof (uint64_t) ==
-                      read (pg->event_fd,
-                            &val,
-                            sizeof (val)));
-      }
-      if ( (pg->pg_sock == pfds[i].fd) &&
-           (0 != (POLLIN & pfds[i].revents)) )
-      {
-        GNUNET_assert (NULL != pg->main_session);
-        GNUNET_PQ_event_do_poll (pg->main_session->conn);
-      }
-    }
-    GNUNET_assert (0 ==
-                   pthread_mutex_lock (&pg->event_lock));
-  }
-  GNUNET_assert (0 ==
-                 pthread_mutex_unlock (&pg->event_lock));
-  return NULL;
-}
-
-
-/**
- * Function called whenever the socket needed for
- * notifications from postgres changes.
- *
- * @param cls closure
- * @param fd socket to listen on, -1 for none
- */
-static void
-pq_socket_cb (void *cls,
-              int fd)
-{
-  struct PostgresClosure *pg = cls;
-  uint64_t val = 1;
-
-  pg->pg_sock = fd;
-  GNUNET_break (sizeof (uint64_t) ==
-                write (pg->event_fd,
-                       &val,
-                       sizeof (val)));
-}
-
-
 /**
  * Register callback to be invoked on events of type @a es.
  *
@@ -2972,7 +2680,7 @@ pq_socket_cb (void *cls,
  * @param cb_cls closure for @a cb
  * @return handle useful to cancel the listener
  */
-static struct TALER_EXCHANGEDB_EventHandler *
+static struct GNUNET_DB_EventHandler *
 postgres_event_listen (void *cls,
                        struct GNUNET_TIME_Relative timeout,
                        const struct GNUNET_DB_EventHeaderP *es,
@@ -2980,36 +2688,12 @@ postgres_event_listen (void *cls,
                        void *cb_cls)
 {
   struct PostgresClosure *pg = cls;
-  struct TALER_EXCHANGEDB_EventHandler *eh;
-  struct TALER_EXCHANGEDB_Session *session;
-
-  session = postgres_get_session (pg);
-  eh = GNUNET_new (struct TALER_EXCHANGEDB_EventHandler);
-  eh->cb = cb;
-  eh->cb_cls = cb_cls;
-  eh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  eh->geh = GNUNET_PQ_event_listen (session->conn,
-                                    es,
-                                    cb,
-                                    cb_cls);
-  GNUNET_assert (NULL != eh->geh);
-  eh->hn = GNUNET_CONTAINER_heap_insert (pg->event_heap,
-                                         eh,
-                                         eh->timeout.abs_value_us);
-  GNUNET_assert (0 ==
-                 pthread_mutex_lock (&pg->event_lock));
-  pg->listener_count++;
-  if (1 == pg->listener_count)
-  {
-    GNUNET_assert (0 ==
-                   pthread_create (&pg->event_thread,
-                                   NULL,
-                                   &handle_events,
-                                   pg));
-  }
-  GNUNET_assert (0 ==
-                 pthread_mutex_unlock (&pg->event_lock));
-  return eh;
+
+  return GNUNET_PQ_event_listen (pg->conn,
+                                 es,
+                                 timeout,
+                                 cb,
+                                 cb_cls);
 }
 
 
@@ -3021,35 +2705,10 @@ postgres_event_listen (void *cls,
  */
 static void
 postgres_event_listen_cancel (void *cls,
-                              struct TALER_EXCHANGEDB_EventHandler *eh)
+                              struct GNUNET_DB_EventHandler *eh)
 {
-  struct PostgresClosure *pg = cls;
-
-  GNUNET_assert (0 ==
-                 pthread_mutex_lock (&pg->event_lock));
-  pg->listener_count--;
-  if (0 == pg->listener_count)
-  {
-    uint64_t val = 1;
-    void *ret;
-
-    GNUNET_break (sizeof (uint64_t) ==
-                  write (pg->event_fd,
-                         &val,
-                         sizeof (val)));
-    GNUNET_break (0 ==
-                  pthread_join (pg->event_thread,
-                                &ret));
-  }
-  GNUNET_assert (0 ==
-                 pthread_mutex_unlock (&pg->event_lock));
-  if (NULL != eh->hn)
-  {
-    GNUNET_CONTAINER_heap_remove_node (eh->hn);
-    eh->hn = NULL;
-  }
-  GNUNET_PQ_event_listen_cancel (eh->geh);
-  GNUNET_free (eh);
+  (void) cls;
+  GNUNET_PQ_event_listen_cancel (eh);
 }
 
 
@@ -3057,22 +2716,19 @@ postgres_event_listen_cancel (void *cls,
  * Notify all that listen on @a es of an event.
  *
  * @param cls database context to use
- * @param session connection to use
  * @param es specification of the event to generate
  * @param extra additional event data provided
  * @param extra_size number of bytes in @a extra
  */
 static void
 postgres_event_notify (void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct GNUNET_DB_EventHeaderP *es,
                        const void *extra,
                        size_t extra_size)
 {
   struct PostgresClosure *pg = cls;
 
-  (void) pg;
-  GNUNET_PQ_event_notify (session->conn,
+  GNUNET_PQ_event_notify (pg->conn,
                           es,
                           extra,
                           extra_size);
@@ -3084,7 +2740,6 @@ postgres_event_notify (void *cls,
  * reference by auditors and other consistency checks.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
  * @param denom_pub the public key used for signing coins of this denomination
  * @param issue issuing information with value, fees and other info about the 
coin
  * @return status of the query
@@ -3092,10 +2747,10 @@ postgres_event_notify (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_insert_denomination_info (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_DenominationPublicKey *denom_pub,
   const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&issue->properties.denom_hash),
     GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key),
@@ -3112,7 +2767,6 @@ postgres_insert_denomination_info (
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
   GNUNET_assert (0 != GNUNET_TIME_absolute_ntoh (
                    issue->properties.start).abs_value_us);
   GNUNET_assert (0 != GNUNET_TIME_absolute_ntoh (
@@ -3135,7 +2789,7 @@ postgres_insert_denomination_info (
                  TALER_amount_cmp_currency_nbo (&issue->properties.value,
                                                 
&issue->properties.fee_refund));
 
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "denomination_insert",
                                              params);
 }
@@ -3145,7 +2799,6 @@ postgres_insert_denomination_info (
  * Fetch information about a denomination key.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
  * @param denom_pub_hash hash of the public key used for signing coins of this 
denomination
  * @param[out] issue set to issue information with value, fees and other info 
about the coin
  * @return transaction status code
@@ -3153,7 +2806,6 @@ postgres_insert_denomination_info (
 static enum GNUNET_DB_QueryStatus
 postgres_get_denomination_info (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *denom_pub_hash,
   struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
 {
@@ -3190,7 +2842,7 @@ postgres_get_denomination_info (
   memset (&issue->properties.master,
           0,
           sizeof (issue->properties.master));
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "denomination_get",
                                                  params,
                                                  rs);
@@ -3302,32 +2954,26 @@ domination_cb_helper (void *cls,
  * Fetch information about all known denomination keys.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
  * @param cb function to call on each denomination key
  * @param cb_cls closure for @a cb
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_iterate_denomination_info (void *cls,
-                                    struct TALER_EXCHANGEDB_Session *session,
                                     TALER_EXCHANGEDB_DenominationCallback cb,
                                     void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
   struct DenomIteratorContext dic = {
     .cb = cb,
     .cb_cls = cb_cls,
-    .pg = pc
+    .pg = pg
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "denomination_iterate",
                                                params,
                                                &domination_cb_helper,
@@ -3432,7 +3078,7 @@ dominations_cb_helper (void *cls,
 /**
 * Function called to invoke @a cb on every known denomination key (revoked
 * and non-revoked) that has been signed by the master key. Runs in its own
-* read-only transaction (hence no session provided).
+* read-only transaction.
 *
 *
  * @param cls the @e cls of this struct with the plugin-specific state
@@ -3445,21 +3091,17 @@ postgres_iterate_denominations (void *cls,
                                 TALER_EXCHANGEDB_DenominationsCallback cb,
                                 void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
   struct DenomsIteratorContext dic = {
     .cb = cb,
     .cb_cls = cb_cls,
-    .pg = pc
+    .pg = pg
   };
-  struct TALER_EXCHANGEDB_Session *session;
 
-  session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "select_denominations",
                                                params,
                                                &dominations_cb_helper,
@@ -3538,8 +3180,7 @@ signkeys_cb_helper (void *cls,
 /**
  * Function called to invoke @a cb on every non-revoked exchange signing key
  * that has been signed by the master key.  Revoked and (for signing!)
- * expired keys are skipped. Runs in its own read-only transaction (hence no
- * session provided).
+ * expired keys are skipped. Runs in its own read-only transaction.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
  * @param cb function to call on each signing key
@@ -3551,7 +3192,7 @@ postgres_iterate_active_signkeys (void *cls,
                                   TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
                                   void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_absolute_time (&now),
@@ -3561,13 +3202,9 @@ postgres_iterate_active_signkeys (void *cls,
     .cb = cb,
     .cb_cls = cb_cls,
   };
-  struct TALER_EXCHANGEDB_Session *session;
 
   now = GNUNET_TIME_absolute_get ();
-  session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "select_signkeys",
                                                params,
                                                &signkeys_cb_helper,
@@ -3642,8 +3279,7 @@ auditors_cb_helper (void *cls,
 
 /**
  * Function called to invoke @a cb on every active auditor. Disabled
- * auditors are skipped. Runs in its own read-only transaction (hence no
- * session provided).
+ * auditors are skipped. Runs in its own read-only transaction.
   *
  * @param cls the @e cls of this struct with the plugin-specific state
  * @param cb function to call on each active auditor
@@ -3655,7 +3291,7 @@ postgres_iterate_active_auditors (void *cls,
                                   TALER_EXCHANGEDB_AuditorsCallback cb,
                                   void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
@@ -3663,12 +3299,8 @@ postgres_iterate_active_auditors (void *cls,
     .cb = cb,
     .cb_cls = cb_cls,
   };
-  struct TALER_EXCHANGEDB_Session *session;
 
-  session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "select_auditors",
                                                params,
                                                &auditors_cb_helper,
@@ -3742,8 +3374,7 @@ auditor_denoms_cb_helper (void *cls,
 /**
  * Function called to invoke @a cb on every denomination with an active
  * auditor. Disabled auditors and denominations without auditor are
- * skipped. Runs in its own read-only transaction (hence no session
- * provided).
+ * skipped. Runs in its own read-only transaction.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
  * @param cb function to call on each active auditor
@@ -3756,7 +3387,7 @@ postgres_iterate_auditor_denominations (
   TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
   void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
@@ -3764,12 +3395,8 @@ postgres_iterate_auditor_denominations (
     .cb = cb,
     .cb_cls = cb_cls,
   };
-  struct TALER_EXCHANGEDB_Session *session;
 
-  session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "select_auditor_denoms",
                                                params,
                                                &auditor_denoms_cb_helper,
@@ -3781,7 +3408,6 @@ postgres_iterate_auditor_denominations (
  * Get the summary of a reserve.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection handle
  * @param[in,out] reserve the reserve data.  The public key of the reserve 
should be
  *          set in this structure; it is used to query the database.  The 
balance
  *          and expiration are then filled accordingly.
@@ -3789,7 +3415,6 @@ postgres_iterate_auditor_denominations (
  */
 static enum GNUNET_DB_QueryStatus
 postgres_reserves_get (void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        struct TALER_EXCHANGEDB_Reserve *reserve)
 {
   struct PostgresClosure *pg = cls;
@@ -3804,7 +3429,7 @@ postgres_reserves_get (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "reserves_get",
                                                    params,
                                                    rs);
@@ -3815,16 +3440,15 @@ postgres_reserves_get (void *cls,
  * Updates a reserve with the data from the given reserve structure.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
  * @param reserve the reserve structure whose data will be used to update the
  *          corresponding record in the database.
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
 reserves_update (void *cls,
-                 struct TALER_EXCHANGEDB_Session *session,
                  const struct TALER_EXCHANGEDB_Reserve *reserve)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     TALER_PQ_query_param_absolute_time (&reserve->expiry),
     TALER_PQ_query_param_absolute_time (&reserve->gc),
@@ -3833,8 +3457,7 @@ reserves_update (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "reserve_update",
                                              params);
 }
@@ -3844,12 +3467,11 @@ reserves_update (void *cls,
  * Generate event notification for the reserve
  * change.
  *
- * @param session database session to use
+ * @param pg plugin state
  * @param reserve_pub reserve to notfiy on
  */
 static void
 notify_on_reserve (struct PostgresClosure *pg,
-                   struct TALER_EXCHANGEDB_Session *session,
                    const struct TALER_ReservePublicKeyP *reserve_pub)
 {
   struct TALER_ReserveEventP rep = {
@@ -3858,8 +3480,9 @@ notify_on_reserve (struct PostgresClosure *pg,
     .reserve_pub = *reserve_pub
   };
 
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Notifying on reserve!\n");
   postgres_event_notify (pg,
-                         session,
                          &rep.header,
                          NULL,
                          0);
@@ -3871,7 +3494,6 @@ notify_on_reserve (struct PostgresClosure *pg,
  * through this function.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection handle
  * @param reserve_pub public key of the reserve
  * @param balance the amount that has to be added to the reserve
  * @param execution_time when was the amount added
@@ -3883,7 +3505,6 @@ notify_on_reserve (struct PostgresClosure *pg,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_reserves_in_insert (void *cls,
-                             struct TALER_EXCHANGEDB_Session *session,
                              const struct TALER_ReservePublicKeyP *reserve_pub,
                              const struct TALER_Amount *balance,
                              struct GNUNET_TIME_Absolute execution_time,
@@ -3936,7 +3557,7 @@ postgres_reserves_in_insert (void *cls,
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Reserve does not exist; creating a new one\n");
     /* Note: query uses 'on conflict do nothing' */
-    qs1 = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+    qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                     "reserve_create",
                                                     params,
                                                     rs);
@@ -3961,7 +3582,7 @@ postgres_reserves_in_insert (void *cls,
         GNUNET_PQ_query_param_end
       };
 
-      qs2 = GNUNET_PQ_eval_prepared_non_select (session->conn,
+      qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                 "reserves_in_add_transaction",
                                                 params);
     }
@@ -3977,7 +3598,7 @@ postgres_reserves_in_insert (void *cls,
         GNUNET_PQ_query_param_end
       };
 
-      qs2 = GNUNET_PQ_eval_prepared_non_select (session->conn,
+      qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                 "reserves_in_add_by_uuid",
                                                 params);
     }
@@ -4002,7 +3623,6 @@ postgres_reserves_in_insert (void *cls,
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs1)
   {
     notify_on_reserve (pg,
-                       session,
                        reserve_pub);
     return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; /* new reserve, we are 
finished */
   }
@@ -4012,13 +3632,11 @@ postgres_reserves_in_insert (void *cls,
   {
     enum GNUNET_DB_QueryStatus cs;
 
-    cs = postgres_commit (cls,
-                          session);
+    cs = postgres_commit (pg);
     if (cs < 0)
       return cs;
     if (GNUNET_OK !=
-        postgres_start (cls,
-                        session,
+        postgres_start (pg,
                         "reserve-update-serializable"))
     {
       GNUNET_break (0);
@@ -4028,8 +3646,7 @@ postgres_reserves_in_insert (void *cls,
   {
     enum GNUNET_DB_QueryStatus reserve_exists;
 
-    reserve_exists = postgres_reserves_get (cls,
-                                            session,
+    reserve_exists = postgres_reserves_get (pg,
                                             &reserve);
     switch (reserve_exists)
     {
@@ -4074,8 +3691,7 @@ postgres_reserves_in_insert (void *cls,
     updated_reserve.gc = GNUNET_TIME_absolute_max (gc,
                                                    reserve.gc);
     (void) GNUNET_TIME_round_abs (&updated_reserve.gc);
-    qs3 = reserves_update (cls,
-                           session,
+    qs3 = reserves_update (pg,
                            &updated_reserve);
     switch (qs3)
     {
@@ -4094,19 +3710,16 @@ postgres_reserves_in_insert (void *cls,
     }
   }
   notify_on_reserve (pg,
-                     session,
                      reserve_pub);
   /* Go back to original transaction mode */
   {
     enum GNUNET_DB_QueryStatus cs;
 
-    cs = postgres_commit (cls,
-                          session);
+    cs = postgres_commit (pg);
     if (cs < 0)
       return cs;
     if (GNUNET_OK !=
-        postgres_start_read_committed (cls,
-                                       session,
+        postgres_start_read_committed (pg,
                                        "reserve-insert-continued"))
     {
       GNUNET_break (0);
@@ -4121,7 +3734,6 @@ postgres_reserves_in_insert (void *cls,
  * Obtain the most recent @a wire_reference that was inserted via @e 
reserves_in_insert.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session the database session handle
  * @param exchange_account_name name of the section in the exchange's 
configuration
  *                       for the account that we are tracking here
  * @param[out] wire_reference set to unique reference identifying the wire 
transfer
@@ -4130,10 +3742,10 @@ postgres_reserves_in_insert (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_get_latest_reserve_in_reference (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const char *exchange_account_name,
   uint64_t *wire_reference)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (exchange_account_name),
     GNUNET_PQ_query_param_end
@@ -4144,8 +3756,7 @@ postgres_get_latest_reserve_in_reference (
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    
"reserves_in_get_latest_wire_reference",
                                                    params,
                                                    rs);
@@ -4157,7 +3768,6 @@ postgres_get_latest_reserve_in_reference (
  * key of the hash of the blinded message.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection to use
  * @param h_blind hash of the blinded coin to be signed (will match
  *                `h_coin_envelope` in the @a collectable to be returned)
  * @param collectable corresponding collectable coin (blind signature)
@@ -4167,7 +3777,6 @@ postgres_get_latest_reserve_in_reference (
 static enum GNUNET_DB_QueryStatus
 postgres_get_withdraw_info (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_blind,
   struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
 {
@@ -4197,13 +3806,13 @@ postgres_get_withdraw_info (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                     "lock_withdraw",
                                                     no_params)))
     return qs;
 #endif
   collectable->h_coin_envelope = *h_blind;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_withdraw_info",
                                                    params,
                                                    rs);
@@ -4215,7 +3824,6 @@ postgres_get_withdraw_info (
  * hash of the blinded message.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection to use
  * @param collectable corresponding collectable coin (blind signature)
  *                    if a coin is found
  * @return query execution status
@@ -4223,7 +3831,6 @@ postgres_get_withdraw_info (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_withdraw_info (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
 {
   struct PostgresClosure *pg = cls;
@@ -4244,7 +3851,7 @@ postgres_insert_withdraw_info (
 
   now = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&now);
-  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                            "insert_withdraw_info",
                                            params);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
@@ -4256,8 +3863,7 @@ postgres_insert_withdraw_info (
   /* update reserve balance */
   reserve.pub = collectable->reserve_pub;
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
-      (qs = postgres_reserves_get (cls,
-                                   session,
+      (qs = postgres_reserves_get (pg,
                                    &reserve)))
   {
     /* Should have been checked before we got here... */
@@ -4285,8 +3891,7 @@ postgres_insert_withdraw_info (
   reserve.gc = GNUNET_TIME_absolute_max (gc,
                                          reserve.gc);
   (void) GNUNET_TIME_round_abs (&reserve.gc);
-  qs = reserves_update (cls,
-                        session,
+  qs = reserves_update (pg,
                         &reserve);
   GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -4590,14 +4195,12 @@ add_exchange_to_bank (void *cls,
  * reserve.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session connection to use
  * @param reserve_pub public key of the reserve
  * @param[out] rhp set to known transaction history (NULL if reserve is 
unknown)
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_reserve_history (void *cls,
-                              struct TALER_EXCHANGEDB_Session *session,
                               const struct TALER_ReservePublicKeyP 
*reserve_pub,
                               struct TALER_EXCHANGEDB_ReserveHistory **rhp)
 {
@@ -4644,7 +4247,7 @@ postgres_get_reserve_history (void *cls,
   qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* make static analysis happy */
   for (unsigned int i = 0; NULL != work[i].cb; i++)
   {
-    qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+    qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                work[i].statement,
                                                params,
                                                work[i].cb,
@@ -4674,7 +4277,6 @@ postgres_get_reserve_history (void *cls,
  * Check if we have the specified deposit already in the database.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection
  * @param deposit deposit to search for
  * @param check_extras whether to check extra fields match or not
  * @param[out] deposit_fee set to the deposit fee the exchange charged
@@ -4685,7 +4287,6 @@ postgres_get_reserve_history (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_have_deposit (void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct TALER_EXCHANGEDB_Deposit *deposit,
                        int check_extras,
                        struct TALER_Amount *deposit_fee,
@@ -4722,7 +4323,7 @@ postgres_have_deposit (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                     "lock_deposit",
                                                     no_params)))
     return qs;
@@ -4730,7 +4331,7 @@ postgres_have_deposit (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Getting deposits for coin %s\n",
               TALER_B2S (&deposit->coin.coin_pub));
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "get_deposit",
                                                  params,
                                                  rs);
@@ -4764,22 +4365,20 @@ postgres_have_deposit (void *cls,
  * @e iterate_ready_deposits()
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param rowid identifies the deposit row to modify
  * @return query result status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_mark_deposit_tiny (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             uint64_t rowid)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&rowid),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "mark_deposit_tiny",
                                              params);
 }
@@ -4790,7 +4389,6 @@ postgres_mark_deposit_tiny (void *cls,
  * refunded anymore.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param coin_pub the coin to check for deposit
  * @param merchant_pub merchant to receive the deposit
  * @param h_contract_terms contract terms of the deposit
@@ -4801,12 +4399,12 @@ postgres_mark_deposit_tiny (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_test_deposit_done (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct TALER_CoinSpendPublicKeyP *coin_pub,
                             const struct TALER_MerchantPublicKeyP 
*merchant_pub,
                             const struct GNUNET_HashCode *h_contract_terms,
                             const struct GNUNET_HashCode *h_wire)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
     GNUNET_PQ_query_param_auto_from_type (merchant_pub),
@@ -4822,8 +4420,7 @@ postgres_test_deposit_done (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "test_deposit_done",
                                                  params,
                                                  rs);
@@ -4843,22 +4440,20 @@ postgres_test_deposit_done (void *cls,
  * @e iterate_ready_deposits() or @e iterate_matching_deposits().
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param rowid identifies the deposit row to modify
  * @return query result status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_mark_deposit_done (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             uint64_t rowid)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&rowid),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "mark_deposit_done",
                                              params);
 }
@@ -4870,14 +4465,12 @@ postgres_mark_deposit_done (void *cls,
  * execution time must be in the past.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param deposit_cb function to call for ONE such deposit
  * @param deposit_cb_cls closure for @a deposit_cb
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_ready_deposit (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             TALER_EXCHANGEDB_DepositIterator deposit_cb,
                             void *deposit_cb_cls)
 {
@@ -4928,7 +4521,7 @@ postgres_get_ready_deposit (void *cls,
               GNUNET_STRINGS_absolute_time_to_string (now),
               (unsigned long long) now.abs_value_us);
 
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "deposits_get_ready",
                                                  params,
                                                  rs);
@@ -5065,7 +4658,6 @@ match_deposit_cb (void *cls,
  * destination.  Those deposits must not already be "done".
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param h_wire destination of the wire transfer
  * @param merchant_pub public key of the merchant
  * @param deposit_cb function to call for each deposit
@@ -5077,7 +4669,6 @@ match_deposit_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_iterate_matching_deposits (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_wire,
   const struct TALER_MerchantPublicKeyP *merchant_pub,
   TALER_EXCHANGEDB_MatchingDepositIterator deposit_cb,
@@ -5099,7 +4690,7 @@ postgres_iterate_matching_deposits (
   mdc.pg = pg;
   mdc.limit = limit;
   mdc.status = GNUNET_OK;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "deposits_iterate_matching",
                                              params,
                                              &match_deposit_cb,
@@ -5119,18 +4710,16 @@ postgres_iterate_matching_deposits (
  * Retrieve the record for a known coin.
  *
  * @param cls the plugin closure
- * @param session the database session handle
  * @param coin_pub the public key of the coin to search for
  * @param coin_info place holder for the returned coin information object
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_known_coin (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_CoinSpendPublicKeyP *coin_pub,
                          struct TALER_CoinPublicInfo *coin_info)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
     GNUNET_PQ_query_param_end
@@ -5147,11 +4736,7 @@ postgres_get_known_coin (void *cls,
               "Getting known coin data for coin %s\n",
               TALER_B2S (coin_pub));
   coin_info->coin_pub = *coin_pub;
-  if (NULL == session)
-    session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_known_coin",
                                                    params,
                                                    rs);
@@ -5162,7 +4747,6 @@ postgres_get_known_coin (void *cls,
  * Retrieve the denomination of a known coin.
  *
  * @param cls the plugin closure
- * @param session the database session handle
  * @param coin_pub the public key of the coin to search for
  * @param[out] denom_hash where to store the hash of the coins denomination
  * @return transaction status code
@@ -5170,11 +4754,10 @@ postgres_get_known_coin (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_get_coin_denomination (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   struct GNUNET_HashCode *denom_hash)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
     GNUNET_PQ_query_param_end
@@ -5188,11 +4771,7 @@ postgres_get_coin_denomination (
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Getting coin denomination of coin %s\n",
               TALER_B2S (coin_pub));
-  if (NULL == session)
-    session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_coin_denomination",
                                                    params,
                                                    rs);
@@ -5205,15 +4784,14 @@ postgres_get_coin_denomination (
  * functionality.
  *
  * @param cls plugin closure
- * @param session the shared database session
  * @param coin_info the public coin info
  * @return query result status
  */
 static enum GNUNET_DB_QueryStatus
 insert_known_coin (void *cls,
-                   struct TALER_EXCHANGEDB_Session *session,
                    const struct TALER_CoinPublicInfo *coin_info)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&coin_info->coin_pub),
     GNUNET_PQ_query_param_auto_from_type (&coin_info->denom_pub_hash),
@@ -5221,11 +4799,10 @@ insert_known_coin (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Creating known coin %s\n",
               TALER_B2S (&coin_info->coin_pub));
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_known_coin",
                                              params);
 }
@@ -5235,15 +4812,14 @@ insert_known_coin (void *cls,
  * Count the number of known coins by denomination.
  *
  * @param cls database connection plugin state
- * @param session database session
  * @param denom_pub_hash denomination to count by
  * @return number of coins if non-negative, otherwise an `enum 
GNUNET_DB_QueryStatus`
  */
 static long long
 postgres_count_known_coins (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct GNUNET_HashCode *denom_pub_hash)
 {
+  struct PostgresClosure *pg = cls;
   uint64_t count;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
@@ -5256,8 +4832,7 @@ postgres_count_known_coins (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "count_known_coins",
                                                  params,
                                                  rs);
@@ -5271,16 +4846,14 @@ postgres_count_known_coins (void *cls,
  * Make sure the given @a coin is known to the database.
  *
  * @param cls database connection plugin state
- * @param session database session
  * @param coin the coin that must be made known
  * @return database transaction status, non-negative on success
  */
 static enum TALER_EXCHANGEDB_CoinKnownStatus
 postgres_ensure_coin_known (void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct TALER_CoinPublicInfo *coin)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_HashCode denom_pub_hash;
   struct GNUNET_PQ_QueryParam params[] = {
@@ -5297,13 +4870,13 @@ postgres_ensure_coin_known (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                     "lock_known_coins",
                                                     no_params)))
     return qs;
 #endif
   /* check if the coin is already known */
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "get_known_coin_dh",
                                                  params,
                                                  rs);
@@ -5324,8 +4897,7 @@ postgres_ensure_coin_known (void *cls,
   }
 
   /* if not known, insert it */
-  qs = insert_known_coin (pc,
-                          session,
+  qs = insert_known_coin (pg,
                           coin);
   switch (qs)
   {
@@ -5347,17 +4919,16 @@ postgres_ensure_coin_known (void *cls,
  * Insert information about deposited coin into the database.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session connection to the database
  * @param exchange_timestamp time the exchange received the deposit request
  * @param deposit deposit information to store
  * @return query result status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_deposit (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          struct GNUNET_TIME_Absolute exchange_timestamp,
                          const struct TALER_EXCHANGEDB_Deposit *deposit)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
     TALER_PQ_query_param_amount (&deposit->amount_with_fee),
@@ -5373,13 +4944,12 @@ postgres_insert_deposit (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Inserting deposit to be executed at %s (%llu/%llu)\n",
               GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
               (unsigned long long) deposit->wire_deadline.abs_value_us,
               (unsigned long long) deposit->refund_deadline.abs_value_us);
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_deposit",
                                              params);
 }
@@ -5389,15 +4959,14 @@ postgres_insert_deposit (void *cls,
  * Insert information about refunded coin into the database.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
  * @param refund refund information to store
  * @return query result status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_refund (void *cls,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_Refund *refund)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub),
     GNUNET_PQ_query_param_auto_from_type (&refund->details.merchant_pub),
@@ -5408,11 +4977,10 @@ postgres_insert_refund (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
   GNUNET_assert (GNUNET_YES ==
                  TALER_amount_cmp_currency (&refund->details.refund_amount,
                                             &refund->details.refund_fee));
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_refund",
                                              params);
 }
@@ -5491,7 +5059,6 @@ get_refunds_cb (void *cls,
  * Select refunds by @a coin_pub, @a merchant_pub and @a h_contract.
  *
  * @param cls closure of plugin
- * @param session database handle to use
  * @param coin_pub coin to get refunds for
  * @param merchant_pub merchant to get refunds for
  * @param h_contract contract (hash) to get refunds for
@@ -5502,7 +5069,6 @@ get_refunds_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_refunds_by_coin (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_MerchantPublicKeyP *merchant_pub,
   const struct GNUNET_HashCode *h_contract,
@@ -5524,7 +5090,7 @@ postgres_select_refunds_by_coin (
     .status = GNUNET_OK
   };
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              
"get_refunds_by_coin_and_contract",
                                              params,
                                              &get_refunds_cb,
@@ -5539,7 +5105,6 @@ postgres_select_refunds_by_coin (
  * Lookup refresh melt commitment data under the given @a rc.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database handle to use, NULL if not run in any transaction
  * @param rc commitment hash to use to locate the operation
  * @param[out] melt where to store the result; note that
  *             melt->session.coin.denom_sig will be set to NULL
@@ -5548,7 +5113,6 @@ postgres_select_refunds_by_coin (
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_melt (void *cls,
-                   struct TALER_EXCHANGEDB_Session *session,
                    const struct TALER_RefreshCommitmentP *rc,
                    struct TALER_EXCHANGEDB_Melt *melt)
 {
@@ -5576,11 +5140,7 @@ postgres_get_melt (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   melt->session.coin.denom_sig.rsa_signature = NULL;
-  if (NULL == session)
-    session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "get_melt",
                                                  params,
                                                  rs);
@@ -5594,7 +5154,6 @@ postgres_get_melt (void *cls,
  * @a rc.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database handle to use
  * @param rc commitment hash to use to locate the operation
  * @param[out] noreveal_index returns the "gamma" value selected by the
  *             exchange which is the index of the transfer key that is
@@ -5603,10 +5162,10 @@ postgres_get_melt (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_melt_index (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_RefreshCommitmentP *rc,
                          uint32_t *noreveal_index)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (rc),
     GNUNET_PQ_query_param_end
@@ -5617,8 +5176,7 @@ postgres_get_melt_index (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_melt_index",
                                                    params,
                                                    rs);
@@ -5629,16 +5187,15 @@ postgres_get_melt_index (void *cls,
  * Store new refresh melt commitment data.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database handle to use
  * @param refresh_session session data to store
  * @return query status for the transaction
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_melt (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_EXCHANGEDB_Refresh *refresh_session)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&refresh_session->rc),
     GNUNET_PQ_query_param_auto_from_type (&refresh_session->coin.coin_pub),
@@ -5648,8 +5205,7 @@ postgres_insert_melt (
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_melt",
                                              params);
 }
@@ -5661,7 +5217,6 @@ postgres_insert_melt (
  * we learned or created in the /refresh/reveal step.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
  * @param rc identify commitment and thus refresh operation
  * @param num_rrcs number of coins to generate, size of the @a rrcs array
  * @param rrcs information about the new coins
@@ -5673,7 +5228,6 @@ postgres_insert_melt (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_refresh_reveal (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_RefreshCommitmentP *rc,
   uint32_t num_rrcs,
   const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs,
@@ -5681,7 +5235,8 @@ postgres_insert_refresh_reveal (
   const struct TALER_TransferPrivateKeyP *tprivs,
   const struct TALER_TransferPublicKeyP *tp)
 {
-  (void) cls;
+  struct PostgresClosure *pg = cls;
+
   if (TALER_CNC_KAPPA != num_tprivs + 1)
   {
     GNUNET_break (0);
@@ -5710,7 +5265,7 @@ postgres_insert_refresh_reveal (
     GNUNET_CRYPTO_hash (rrc->coin_ev,
                         rrc->coin_ev_size,
                         &h_coin_ev);
-    qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_refresh_revealed_coin",
                                              params);
     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
@@ -5722,12 +5277,13 @@ postgres_insert_refresh_reveal (
       GNUNET_PQ_query_param_auto_from_type (rc),
       GNUNET_PQ_query_param_auto_from_type (tp),
       GNUNET_PQ_query_param_fixed_size (tprivs,
-                                        num_tprivs * sizeof (struct
-                                                             
TALER_TransferPrivateKeyP)),
+                                        num_tprivs
+                                        * sizeof (struct
+                                                  TALER_TransferPrivateKeyP)),
       GNUNET_PQ_query_param_end
     };
 
-    return GNUNET_PQ_eval_prepared_non_select (session->conn,
+    return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                "insert_refresh_transfer_keys",
                                                params);
   }
@@ -5820,7 +5376,6 @@ add_revealed_coins (void *cls,
  * create in the given refresh operation.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection
  * @param rc identify commitment and thus refresh operation
  * @param cb function to call with the results
  * @param cb_cls closure for @a cb
@@ -5828,11 +5383,11 @@ add_revealed_coins (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_refresh_reveal (void *cls,
-                             struct TALER_EXCHANGEDB_Session *session,
                              const struct TALER_RefreshCommitmentP *rc,
                              TALER_EXCHANGEDB_RefreshCallback cb,
                              void *cb_cls)
 {
+  struct PostgresClosure *pg = cls;
   struct GetRevealContext grctx;
   enum GNUNET_DB_QueryStatus qs;
   struct TALER_TransferPublicKeyP tp;
@@ -5851,12 +5406,11 @@ postgres_get_refresh_reveal (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
   /* First get the coins */
   memset (&grctx,
           0,
           sizeof (grctx));
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "get_refresh_revealed_coins",
                                              params,
                                              &add_revealed_coins,
@@ -5882,7 +5436,7 @@ postgres_get_refresh_reveal (void *cls,
   }
 
   /* now also get the transfer keys (public and private) */
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "get_refresh_transfer_keys",
                                                  params,
                                                  rs);
@@ -5978,7 +5532,6 @@ free_link_data_list (void *cls,
 {
   struct TALER_EXCHANGEDB_LinkList *next;
 
-  (void) cls;
   while (NULL != ldl)
   {
     next = ldl->next;
@@ -6065,7 +5618,6 @@ add_ldl (void *cls,
  * information, the denomination keys and the signatures.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection
  * @param coin_pub public key of the coin
  * @param ldc function to call for each session the coin was melted into
  * @param ldc_cls closure for @a tdc
@@ -6073,11 +5625,11 @@ add_ldl (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_link_data (void *cls,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_CoinSpendPublicKeyP *coin_pub,
                         TALER_EXCHANGEDB_LinkCallback ldc,
                         void *ldc_cls)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
     GNUNET_PQ_query_param_end
@@ -6089,7 +5641,7 @@ postgres_get_link_data (void *cls,
   ldctx.ldc_cls = ldc_cls;
   ldctx.last = NULL;
   ldctx.status = GNUNET_OK;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "get_link",
                                              params,
                                              &add_ldl,
@@ -6133,11 +5685,6 @@ struct CoinHistoryContext
    */
   void *db_cls;
 
-  /**
-   * Database session we are using.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
-
   /**
    * Plugin context.
    */
@@ -6578,7 +6125,6 @@ struct Work
  * (/refresh/melt, /deposit, /refund and /recoup operations).
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database connection
  * @param coin_pub coin to investigate
  * @param include_recoup should recoup transactions be included in the @a tlp
  * @param[out] tlp set to list of transactions, NULL if coin is fresh
@@ -6587,7 +6133,6 @@ struct Work
 static enum GNUNET_DB_QueryStatus
 postgres_get_coin_transactions (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   int include_recoup,
   struct TALER_EXCHANGEDB_TransactionList **tlp)
@@ -6635,7 +6180,6 @@ postgres_get_coin_transactions (
   struct CoinHistoryContext chc = {
     .head = NULL,
     .coin_pub = coin_pub,
-    .session = session,
     .pg = pg,
     .db_cls = cls
   };
@@ -6646,7 +6190,7 @@ postgres_get_coin_transactions (
               TALER_B2S (coin_pub));
   for (unsigned int i = 0; NULL != work[i].statement; i++)
   {
-    qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+    qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                work[i].statement,
                                                params,
                                                work[i].cb,
@@ -6777,7 +6321,6 @@ handle_wt_result (void *cls,
  * into a wire transfer by the respective @a wtid.
  *
  * @param cls closure
- * @param session database connection
  * @param wtid the raw wire transfer identifier we used
  * @param cb function to call on each transaction found
  * @param cb_cls closure for @a cb
@@ -6786,7 +6329,6 @@ handle_wt_result (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_wire_transfer (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_WireTransferIdentifierRawP *wtid,
   TALER_EXCHANGEDB_AggregationDataCallback cb,
   void *cb_cls)
@@ -6804,7 +6346,7 @@ postgres_lookup_wire_transfer (
   ctx.pg = pg;
   ctx.status = GNUNET_OK;
   /* check if the melt record exists and get it */
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "lookup_transactions",
                                              params,
                                              &handle_wt_result,
@@ -6821,7 +6363,6 @@ postgres_lookup_wire_transfer (
  * to be executed.
  *
  * @param cls closure
- * @param session database connection
  * @param h_contract_terms hash of the proposal data
  * @param h_wire hash of merchant wire details
  * @param coin_pub public key of deposited coin
@@ -6833,7 +6374,6 @@ postgres_lookup_wire_transfer (
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_transfer_by_deposit (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_contract_terms,
   const struct GNUNET_HashCode *h_wire,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
@@ -6867,7 +6407,7 @@ postgres_lookup_transfer_by_deposit (
   };
 
   /* check if the melt record exists and get it */
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "lookup_deposit_wtid",
                                                  params,
                                                  rs);
@@ -6907,7 +6447,7 @@ postgres_lookup_transfer_by_deposit (
       GNUNET_PQ_result_spec_end
     };
 
-    qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_deposit_for_wtid",
                                                    params2,
                                                    rs2);
@@ -6931,7 +6471,6 @@ postgres_lookup_transfer_by_deposit (
  * Function called to insert aggregation information into the DB.
  *
  * @param cls closure
- * @param session database connection
  * @param wtid the raw wire transfer identifier we used
  * @param deposit_serial_id row in the deposits table for which this is 
aggregation data
  * @return transaction status code
@@ -6939,10 +6478,10 @@ postgres_lookup_transfer_by_deposit (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_aggregation_tracking (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_WireTransferIdentifierRawP *wtid,
   unsigned long long deposit_serial_id)
 {
+  struct PostgresClosure *pg = cls;
   uint64_t rid = deposit_serial_id;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&rid),
@@ -6950,8 +6489,7 @@ postgres_insert_aggregation_tracking (
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_aggregation_tracking",
                                              params);
 }
@@ -6961,7 +6499,6 @@ postgres_insert_aggregation_tracking (
  * Obtain wire fee from database.
  *
  * @param cls closure
- * @param session database connection
  * @param type type of wire transfer the fee applies for
  * @param date for which date do we want the fee?
  * @param[out] start_date when does the fee go into effect
@@ -6973,7 +6510,6 @@ postgres_insert_aggregation_tracking (
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_wire_fee (void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const char *type,
                        struct GNUNET_TIME_Absolute date,
                        struct GNUNET_TIME_Absolute *start_date,
@@ -6997,7 +6533,7 @@ postgres_get_wire_fee (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "get_wire_fee",
                                                    params,
                                                    rs);
@@ -7008,7 +6544,6 @@ postgres_get_wire_fee (void *cls,
  * Insert wire transfer fee into database.
  *
  * @param cls closure
- * @param session database connection
  * @param type type of wire transfer this fee applies for
  * @param start_date when does the fee go into effect
  * @param end_date when does the fee end being valid
@@ -7019,7 +6554,6 @@ postgres_get_wire_fee (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_wire_fee (void *cls,
-                          struct TALER_EXCHANGEDB_Session *session,
                           const char *type,
                           struct GNUNET_TIME_Absolute start_date,
                           struct GNUNET_TIME_Absolute end_date,
@@ -7045,7 +6579,6 @@ postgres_insert_wire_fee (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = postgres_get_wire_fee (pg,
-                              session,
                               type,
                               start_date,
                               &sd,
@@ -7085,7 +6618,7 @@ postgres_insert_wire_fee (void *cls,
     return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
   }
 
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_wire_fee",
                                              params);
 }
@@ -7181,7 +6714,6 @@ reserve_expired_cb (void *cls,
  * remaining balances.
  *
  * @param cls closure of the plugin
- * @param session database connection
  * @param now timestamp based on which we decide expiration
  * @param rec function to call on expired reserves
  * @param rec_cls closure for @a rec
@@ -7189,7 +6721,6 @@ reserve_expired_cb (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_expired_reserves (void *cls,
-                               struct TALER_EXCHANGEDB_Session *session,
                                struct GNUNET_TIME_Absolute now,
                                TALER_EXCHANGEDB_ReserveExpiredCallback rec,
                                void *rec_cls)
@@ -7206,7 +6737,7 @@ postgres_get_expired_reserves (void *cls,
   ectx.rec_cls = rec_cls;
   ectx.pg = pg;
   ectx.status = GNUNET_OK;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "get_expired_reserves",
                                              params,
                                              &reserve_expired_cb,
@@ -7221,7 +6752,6 @@ postgres_get_expired_reserves (void *cls,
  * Insert reserve close operation into database.
  *
  * @param cls closure
- * @param session database connection
  * @param reserve_pub which reserve is this about?
  * @param execution_date when did we perform the transfer?
  * @param receiver_account to which account do we transfer?
@@ -7233,7 +6763,6 @@ postgres_get_expired_reserves (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_insert_reserve_closed (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ReservePublicKeyP *reserve_pub,
   struct GNUNET_TIME_Absolute execution_date,
   const char *receiver_account,
@@ -7241,6 +6770,7 @@ postgres_insert_reserve_closed (
   const struct TALER_Amount *amount_with_fee,
   const struct TALER_Amount *closing_fee)
 {
+  struct PostgresClosure *pg = cls;
   struct TALER_EXCHANGEDB_Reserve reserve;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
@@ -7254,7 +6784,7 @@ postgres_insert_reserve_closed (
   enum TALER_AmountArithmeticResult ret;
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                            "reserves_close_insert",
                                            params);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
@@ -7264,7 +6794,6 @@ postgres_insert_reserve_closed (
   reserve.pub = *reserve_pub;
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       (qs = postgres_reserves_get (cls,
-                                   session,
                                    &reserve)))
   {
     /* Existence should have been checked before we got here... */
@@ -7288,7 +6817,6 @@ postgres_insert_reserve_closed (
   }
   GNUNET_break (TALER_AAR_RESULT_ZERO == ret);
   return reserves_update (cls,
-                          session,
                           &reserve);
 }
 
@@ -7297,7 +6825,6 @@ postgres_insert_reserve_closed (
  * Function called to insert wire transfer commit data into the DB.
  *
  * @param cls closure
- * @param session database connection
  * @param type type of the wire transfer (i.e. "iban")
  * @param buf buffer with wire transfer preparation data
  * @param buf_size number of bytes in @a buf
@@ -7305,19 +6832,18 @@ postgres_insert_reserve_closed (
  */
 static enum GNUNET_DB_QueryStatus
 postgres_wire_prepare_data_insert (void *cls,
-                                   struct TALER_EXCHANGEDB_Session *session,
                                    const char *type,
                                    const char *buf,
                                    size_t buf_size)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (type),
     GNUNET_PQ_query_param_fixed_size (buf, buf_size),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "wire_prepare_data_insert",
                                              params);
 }
@@ -7327,23 +6853,21 @@ postgres_wire_prepare_data_insert (void *cls,
  * Function called to mark wire transfer commit data as finished.
  *
  * @param cls closure
- * @param session database connection
  * @param rowid which entry to mark as finished
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_wire_prepare_data_mark_finished (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t rowid)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&rowid),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "wire_prepare_data_mark_done",
                                              params);
 }
@@ -7353,23 +6877,21 @@ postgres_wire_prepare_data_mark_finished (
  * Function called to mark wire transfer commit data as failed.
  *
  * @param cls closure
- * @param session database connection
  * @param rowid which entry to mark as failed
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_wire_prepare_data_mark_failed (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t rowid)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&rowid),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "wire_prepare_data_mark_failed",
                                              params);
 }
@@ -7380,17 +6902,16 @@ postgres_wire_prepare_data_mark_failed (
  * preparation data. Fetches at most one item.
  *
  * @param cls closure
- * @param session database connection
  * @param cb function to call for ONE unfinished item
  * @param cb_cls closure for @a cb
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_wire_prepare_data_get (void *cls,
-                                struct TALER_EXCHANGEDB_Session *session,
                                 TALER_EXCHANGEDB_WirePreparationIterator cb,
                                 void *cb_cls)
 {
+  struct PostgresClosure *pg = cls;
   enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
@@ -7410,8 +6931,7 @@ postgres_wire_prepare_data_get (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "wire_prepare_data_get",
                                                  params,
                                                  rs);
@@ -7433,34 +6953,32 @@ postgres_wire_prepare_data_get (void *cls,
  * and only add the wire transfer out at the end.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
  * @return #GNUNET_OK on success
  */
 static int
-postgres_start_deferred_wire_out (void *cls,
-                                  struct TALER_EXCHANGEDB_Session *session)
+postgres_start_deferred_wire_out (void *cls)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
     GNUNET_PQ_make_execute ("SET CONSTRAINTS wire_out_ref DEFERRED"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
-  postgres_preflight (cls,
-                      session);
+  if (GNUNET_SYSERR ==
+      postgres_preflight (pg))
+    return GNUNET_SYSERR;
   if (GNUNET_OK !=
-      postgres_start (cls,
-                      session,
+      postgres_start (pg,
                       "deferred wire out"))
     return GNUNET_SYSERR;
   if (GNUNET_OK !=
-      GNUNET_PQ_exec_statements (session->conn,
+      GNUNET_PQ_exec_statements (pg->conn,
                                  es))
   {
     TALER_LOG_ERROR (
       "Failed to defer wire_out_ref constraint on transaction\n");
     GNUNET_break (0);
-    postgres_rollback (cls,
-                       session);
+    postgres_rollback (pg);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
@@ -7471,7 +6989,6 @@ postgres_start_deferred_wire_out (void *cls,
  * Store information about an outgoing wire transfer that was executed.
  *
  * @param cls closure
- * @param session database connection
  * @param date time of the wire transfer
  * @param wtid subject of the wire transfer
  * @param wire_account details about the receiver account of the wire transfer
@@ -7483,13 +7000,13 @@ postgres_start_deferred_wire_out (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_store_wire_transfer_out (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   struct GNUNET_TIME_Absolute date,
   const struct TALER_WireTransferIdentifierRawP *wtid,
   const json_t *wire_account,
   const char *exchange_account_section,
   const struct TALER_Amount *amount)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     TALER_PQ_query_param_absolute_time (&date),
     GNUNET_PQ_query_param_auto_from_type (wtid),
@@ -7499,8 +7016,7 @@ postgres_store_wire_transfer_out (
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_wire_out",
                                              params);
 }
@@ -7720,7 +7236,6 @@ deposit_serial_helper_cb (void *cls,
  * order.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
@@ -7729,7 +7244,6 @@ deposit_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_deposits_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_DepositCallback cb,
   void *cb_cls)
@@ -7747,7 +7261,7 @@ postgres_select_deposits_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "audit_get_deposits_incr",
                                              params,
                                              &deposit_serial_helper_cb,
@@ -7859,7 +7373,6 @@ refreshs_serial_helper_cb (void *cls,
  * order.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
@@ -7868,7 +7381,6 @@ refreshs_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_refreshes_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_RefreshesCallback cb,
   void *cb_cls)
@@ -7886,7 +7398,7 @@ postgres_select_refreshes_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              
"audit_get_refresh_commitments_incr",
                                              params,
                                              &refreshs_serial_helper_cb,
@@ -7997,7 +7509,6 @@ refunds_serial_helper_cb (void *cls,
  * order.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
@@ -8006,7 +7517,6 @@ refunds_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_refunds_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_RefundCallback cb,
   void *cb_cls)
@@ -8024,7 +7534,7 @@ postgres_select_refunds_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "audit_get_refunds_incr",
                                              params,
                                              &refunds_serial_helper_cb,
@@ -8132,7 +7642,6 @@ reserves_in_serial_helper_cb (void *cls,
  * in monotonically increasing order.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
@@ -8141,7 +7650,6 @@ reserves_in_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_reserves_in_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_ReserveInCallback cb,
   void *cb_cls)
@@ -8159,7 +7667,7 @@ postgres_select_reserves_in_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              
"audit_reserves_in_get_transactions_incr",
                                              params,
                                              &reserves_in_serial_helper_cb,
@@ -8175,7 +7683,6 @@ postgres_select_reserves_in_above_serial_id (
  * in monotonically increasing order by account.
  *
  * @param cls closure
- * @param session database connection
  * @param account_name name of the account to select by
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
@@ -8185,7 +7692,6 @@ postgres_select_reserves_in_above_serial_id (
 static enum GNUNET_DB_QueryStatus
 postgres_select_reserves_in_above_serial_id_by_account (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const char *account_name,
   uint64_t serial_id,
   TALER_EXCHANGEDB_ReserveInCallback cb,
@@ -8205,7 +7711,7 @@ postgres_select_reserves_in_above_serial_id_by_account (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              
"audit_reserves_in_get_transactions_incr_by_account",
                                              params,
                                              &reserves_in_serial_helper_cb,
@@ -8317,7 +7823,6 @@ reserves_out_serial_helper_cb (void *cls,
  * in monotonically increasing order.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
@@ -8326,7 +7831,6 @@ reserves_out_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_withdrawals_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_WithdrawCallback cb,
   void *cb_cls)
@@ -8344,7 +7848,7 @@ postgres_select_withdrawals_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "audit_get_reserves_out_incr",
                                              params,
                                              &reserves_out_serial_helper_cb,
@@ -8448,7 +7952,6 @@ wire_out_serial_helper_cb (void *cls,
  * executed.
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call for ONE unfinished item
  * @param cb_cls closure for @a cb
@@ -8457,7 +7960,6 @@ wire_out_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_wire_out_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_WireTransferOutCallback cb,
   void *cb_cls)
@@ -8475,7 +7977,7 @@ postgres_select_wire_out_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "audit_get_wire_incr",
                                              params,
                                              &wire_out_serial_helper_cb,
@@ -8491,7 +7993,6 @@ postgres_select_wire_out_above_serial_id (
  * executed by account.
  *
  * @param cls closure
- * @param session database connection
  * @param account_name account to select
  * @param serial_id highest serial ID to exclude (select strictly larger)
  * @param cb function to call for ONE unfinished item
@@ -8501,7 +8002,6 @@ postgres_select_wire_out_above_serial_id (
 static enum GNUNET_DB_QueryStatus
 postgres_select_wire_out_above_serial_id_by_account (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const char *account_name,
   uint64_t serial_id,
   TALER_EXCHANGEDB_WireTransferOutCallback cb,
@@ -8521,7 +8021,7 @@ postgres_select_wire_out_above_serial_id_by_account (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "audit_get_wire_incr_by_account",
                                              params,
                                              &wire_out_serial_helper_cb,
@@ -8644,7 +8144,6 @@ recoup_serial_helper_cb (void *cls,
  * received, ordered by serial ID (monotonically increasing).
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id lowest serial ID to include (select larger or equal)
  * @param cb function to call for ONE unfinished item
  * @param cb_cls closure for @a cb
@@ -8653,7 +8152,6 @@ recoup_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_recoup_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_RecoupCallback cb,
   void *cb_cls)
@@ -8671,7 +8169,7 @@ postgres_select_recoup_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "recoup_get_incr",
                                              params,
                                              &recoup_serial_helper_cb,
@@ -8798,7 +8296,6 @@ recoup_refresh_serial_helper_cb (void *cls,
  * refreshed coins, ordered by serial ID (monotonically increasing).
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id lowest serial ID to include (select larger or equal)
  * @param cb function to call for ONE unfinished item
  * @param cb_cls closure for @a cb
@@ -8807,7 +8304,6 @@ recoup_refresh_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_recoup_refresh_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_RecoupRefreshCallback cb,
   void *cb_cls)
@@ -8825,7 +8321,7 @@ postgres_select_recoup_refresh_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "recoup_refresh_get_incr",
                                              params,
                                              &recoup_refresh_serial_helper_cb,
@@ -8937,7 +8433,6 @@ reserve_closed_serial_helper_cb (void *cls,
  * triggered, ordered by serial ID (monotonically increasing).
  *
  * @param cls closure
- * @param session database connection
  * @param serial_id lowest serial ID to include (select larger or equal)
  * @param cb function to call for ONE unfinished item
  * @param cb_cls closure for @a cb
@@ -8946,7 +8441,6 @@ reserve_closed_serial_helper_cb (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_select_reserve_closed_above_serial_id (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   uint64_t serial_id,
   TALER_EXCHANGEDB_ReserveClosedCallback cb,
   void *cb_cls)
@@ -8964,7 +8458,7 @@ postgres_select_reserve_closed_above_serial_id (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "reserves_close_get_incr",
                                              params,
                                              &reserve_closed_serial_helper_cb,
@@ -8982,7 +8476,6 @@ postgres_select_reserve_closed_above_serial_id (
  * wire transfer back to the customer's account for the reserve.
  *
  * @param cls closure
- * @param session database connection
  * @param reserve_pub public key of the reserve that is being refunded
  * @param coin information about the coin
  * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_RECOUP
@@ -8995,7 +8488,6 @@ postgres_select_reserve_closed_above_serial_id (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_recoup_request (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ReservePublicKeyP *reserve_pub,
   const struct TALER_CoinPublicInfo *coin,
   const struct TALER_CoinSpendSignatureP *coin_sig,
@@ -9020,7 +8512,7 @@ postgres_insert_recoup_request (
   enum GNUNET_DB_QueryStatus qs;
 
   /* now store actual recoup information */
-  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                            "recoup_insert",
                                            params);
   if (0 > qs)
@@ -9031,8 +8523,7 @@ postgres_insert_recoup_request (
 
   /* Update reserve balance */
   reserve.pub = *reserve_pub;
-  qs = postgres_reserves_get (cls,
-                              session,
+  qs = postgres_reserves_get (pg,
                               &reserve);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
   {
@@ -9060,8 +8551,7 @@ postgres_insert_recoup_request (
   reserve.expiry = GNUNET_TIME_absolute_max (expiry,
                                              reserve.expiry);
   (void) GNUNET_TIME_round_abs (&reserve.expiry);
-  qs = reserves_update (cls,
-                        session,
+  qs = reserves_update (pg,
                         &reserve);
   if (0 >= qs)
   {
@@ -9079,7 +8569,6 @@ postgres_insert_recoup_request (
  * "recoup_by_old_coin" used in #postgres_get_coin_transactions()).
  *
  * @param cls closure
- * @param session database connection
  * @param coin public information about the refreshed coin
  * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_RECOUP
  * @param coin_blind blinding key of the coin
@@ -9092,7 +8581,6 @@ postgres_insert_recoup_request (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_recoup_refresh_request (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_CoinPublicInfo *coin,
   const struct TALER_CoinSpendSignatureP *coin_sig,
   const struct TALER_DenominationBlindingKeyP *coin_blind,
@@ -9100,6 +8588,7 @@ postgres_insert_recoup_refresh_request (
   const struct GNUNET_HashCode *h_blind_ev,
   struct GNUNET_TIME_Absolute timestamp)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
     GNUNET_PQ_query_param_auto_from_type (coin_sig),
@@ -9111,12 +8600,11 @@ postgres_insert_recoup_refresh_request (
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) cls;
   /* now store actual recoup information */
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Inserting recoup-refresh for coin %s\n",
               TALER_B2S (&coin->coin_pub));
-  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                            "recoup_refresh_insert",
                                            params);
   if (0 > qs)
@@ -9133,17 +8621,16 @@ postgres_insert_recoup_refresh_request (
  * from given the hash of the blinded coin.
  *
  * @param cls closure
- * @param session a session
  * @param h_blind_ev hash of the blinded coin
  * @param[out] reserve_pub set to information about the reserve (on success 
only)
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_reserve_by_h_blind (void *cls,
-                                 struct TALER_EXCHANGEDB_Session *session,
                                  const struct GNUNET_HashCode *h_blind_ev,
                                  struct TALER_ReservePublicKeyP *reserve_pub)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
     GNUNET_PQ_query_param_end
@@ -9154,8 +8641,7 @@ postgres_get_reserve_by_h_blind (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "reserve_by_h_blind",
                                                    params,
                                                    rs);
@@ -9167,17 +8653,16 @@ postgres_get_reserve_by_h_blind (void *cls,
  * given the hash of the blinded (fresh) coin.
  *
  * @param cls closure
- * @param session a session
  * @param h_blind_ev hash of the blinded coin
  * @param[out] old_coin_pub set to information about the old coin (on success 
only)
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_old_coin_by_h_blind (void *cls,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   const struct GNUNET_HashCode *h_blind_ev,
                                   struct TALER_CoinSpendPublicKeyP 
*old_coin_pub)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
     GNUNET_PQ_query_param_end
@@ -9188,8 +8673,7 @@ postgres_get_old_coin_by_h_blind (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "old_coin_by_h_blind",
                                                    params,
                                                    rs);
@@ -9201,7 +8685,6 @@ postgres_get_old_coin_by_h_blind (void *cls,
  * in the database.
  *
  * @param cls closure
- * @param session a session
  * @param denom_pub_hash hash of the revoked denomination key
  * @param master_sig signature affirming the revocation
  * @return transaction status code
@@ -9209,23 +8692,17 @@ postgres_get_old_coin_by_h_blind (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_insert_denomination_revocation (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *denom_pub_hash,
   const struct TALER_MasterSignatureP *master_sig)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
     GNUNET_PQ_query_param_auto_from_type (master_sig),
     GNUNET_PQ_query_param_end
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "denomination_revocation_insert",
                                              params);
 }
@@ -9236,7 +8713,6 @@ postgres_insert_denomination_revocation (
  * the database.
  *
  * @param cls closure
- * @param session a session
  * @param denom_pub_hash hash of the revoked denomination key
  * @param[out] master_sig signature affirming the revocation
  * @param[out] rowid row where the information is stored
@@ -9245,11 +8721,11 @@ postgres_insert_denomination_revocation (
 static enum GNUNET_DB_QueryStatus
 postgres_get_denomination_revocation (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *denom_pub_hash,
   struct TALER_MasterSignatureP *master_sig,
   uint64_t *rowid)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
     GNUNET_PQ_query_param_end
@@ -9260,8 +8736,7 @@ postgres_get_denomination_revocation (
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    
"denomination_revocation_get",
                                                    params,
                                                    rs);
@@ -9365,7 +8840,6 @@ missing_wire_cb (void *cls,
  * been deposited between @a start_date and @a end_date.
  *
  * @param cls closure
- * @param session a session
  * @param start_date lower bound on the requested wire execution date
  * @param end_date upper bound on the requested wire execution date
  * @param cb function to call on all such deposits
@@ -9374,7 +8848,6 @@ missing_wire_cb (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_select_deposits_missing_wire (void *cls,
-                                       struct TALER_EXCHANGEDB_Session 
*session,
                                        struct GNUNET_TIME_Absolute start_date,
                                        struct GNUNET_TIME_Absolute end_date,
                                        TALER_EXCHANGEDB_WireMissingCallback cb,
@@ -9394,7 +8867,7 @@ postgres_select_deposits_missing_wire (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "deposits_get_overdue",
                                              params,
                                              &missing_wire_cb,
@@ -9409,7 +8882,6 @@ postgres_select_deposits_missing_wire (void *cls,
  * Check the last date an auditor was modified.
  *
  * @param cls closure
- * @param session a session
  * @param auditor_pub key to look up information for
  * @param[out] last_date last modification date to auditor status
  * @return transaction status code
@@ -9417,10 +8889,10 @@ postgres_select_deposits_missing_wire (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_auditor_timestamp (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_AuditorPublicKeyP *auditor_pub,
   struct GNUNET_TIME_Absolute *last_date)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
     GNUNET_PQ_query_param_end
@@ -9431,8 +8903,7 @@ postgres_lookup_auditor_timestamp (
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "lookup_auditor_timestamp",
                                                    params,
                                                    rs);
@@ -9443,7 +8914,6 @@ postgres_lookup_auditor_timestamp (
  * Lookup current state of an auditor.
  *
  * @param cls closure
- * @param session a session
  * @param auditor_pub key to look up information for
  * @param[out] auditor_url set to the base URL of the auditor's REST API; 
memory to be
  *            released by the caller!
@@ -9451,13 +8921,13 @@ postgres_lookup_auditor_timestamp (
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
-postgres_lookup_auditor_status (void *cls,
-                                struct TALER_EXCHANGEDB_Session *session,
-                                const struct
-                                TALER_AuditorPublicKeyP *auditor_pub,
-                                char **auditor_url,
-                                bool *enabled)
+postgres_lookup_auditor_status (
+  void *cls,
+  const struct TALER_AuditorPublicKeyP *auditor_pub,
+  char **auditor_url,
+  bool *enabled)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
     GNUNET_PQ_query_param_end
@@ -9472,8 +8942,7 @@ postgres_lookup_auditor_status (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "lookup_auditor_status",
                                                  params,
                                                  rs);
@@ -9486,7 +8955,6 @@ postgres_lookup_auditor_status (void *cls,
  * Insert information about an auditor that will audit this exchange.
  *
  * @param cls closure
- * @param session a session
  * @param auditor_pub key of the auditor
  * @param auditor_url base URL of the auditor's REST service
  * @param auditor_name name of the auditor (for humans)
@@ -9496,12 +8964,12 @@ postgres_lookup_auditor_status (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_auditor (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_AuditorPublicKeyP *auditor_pub,
                          const char *auditor_url,
                          const char *auditor_name,
                          struct GNUNET_TIME_Absolute start_date)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
     GNUNET_PQ_query_param_string (auditor_name),
@@ -9510,8 +8978,7 @@ postgres_insert_auditor (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_auditor",
                                              params);
 }
@@ -9521,7 +8988,6 @@ postgres_insert_auditor (void *cls,
  * Update information about an auditor that will audit this exchange.
  *
  * @param cls closure
- * @param session a session
  * @param auditor_pub key of the auditor (primary key for the existing record)
  * @param auditor_url base URL of the auditor's REST service, to be updated
  * @param auditor_name name of the auditor (for humans)
@@ -9532,13 +8998,13 @@ postgres_insert_auditor (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_update_auditor (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_AuditorPublicKeyP *auditor_pub,
                          const char *auditor_url,
                          const char *auditor_name,
                          struct GNUNET_TIME_Absolute change_date,
                          bool enabled)
 {
+  struct PostgresClosure *pg = cls;
   uint8_t enabled8 = enabled ? 1 : 0;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
@@ -9549,8 +9015,7 @@ postgres_update_auditor (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "update_auditor",
                                              params);
 }
@@ -9560,17 +9025,16 @@ postgres_update_auditor (void *cls,
  * Check the last date an exchange wire account was modified.
  *
  * @param cls closure
- * @param session a session
  * @param payto_uri key to look up information for
  * @param[out] last_date last modification date to auditor status
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_wire_timestamp (void *cls,
-                                struct TALER_EXCHANGEDB_Session *session,
                                 const char *payto_uri,
                                 struct GNUNET_TIME_Absolute *last_date)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (payto_uri),
     GNUNET_PQ_query_param_end
@@ -9581,8 +9045,7 @@ postgres_lookup_wire_timestamp (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "lookup_wire_timestamp",
                                                    params,
                                                    rs);
@@ -9593,7 +9056,6 @@ postgres_lookup_wire_timestamp (void *cls,
  * Insert information about an wire account used by this exchange.
  *
  * @param cls closure
- * @param session a session
  * @param payto_uri wire account of the exchange
  * @param start_date date when the account was added by the offline system
  *                      (only to be used for replay detection)
@@ -9603,11 +9065,11 @@ postgres_lookup_wire_timestamp (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_wire (void *cls,
-                      struct TALER_EXCHANGEDB_Session *session,
                       const char *payto_uri,
                       struct GNUNET_TIME_Absolute start_date,
                       const struct TALER_MasterSignatureP *master_sig)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (payto_uri),
     GNUNET_PQ_query_param_auto_from_type (master_sig),
@@ -9615,8 +9077,7 @@ postgres_insert_wire (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_wire",
                                              params);
 }
@@ -9626,7 +9087,6 @@ postgres_insert_wire (void *cls,
  * Update information about a wire account of the exchange.
  *
  * @param cls closure
- * @param session a session
  * @param payto_uri account the update is about
  * @param change_date date when the account status was last changed
  *                      (only to be used for replay detection)
@@ -9635,11 +9095,11 @@ postgres_insert_wire (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_update_wire (void *cls,
-                      struct TALER_EXCHANGEDB_Session *session,
                       const char *payto_uri,
                       struct GNUNET_TIME_Absolute change_date,
                       bool enabled)
 {
+  struct PostgresClosure *pg = cls;
   uint8_t enabled8 = enabled ? 1 : 0;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (payto_uri),
@@ -9648,8 +9108,7 @@ postgres_update_wire (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "update_wire",
                                              params);
 }
@@ -9744,12 +9203,8 @@ postgres_get_wire_accounts (void *cls,
     GNUNET_PQ_query_param_end
   };
   enum GNUNET_DB_QueryStatus qs;
-  struct TALER_EXCHANGEDB_Session *session;
 
-  session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "get_wire_accounts",
                                              params,
                                              &get_wire_accounts_cb,
@@ -9873,12 +9328,8 @@ postgres_get_wire_fees (void *cls,
     .status = GNUNET_OK
   };
   enum GNUNET_DB_QueryStatus qs;
-  struct TALER_EXCHANGEDB_Session *session;
 
-  session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              "get_wire_fees",
                                              params,
                                              &get_wire_fees_cb,
@@ -9893,7 +9344,6 @@ postgres_get_wire_fees (void *cls,
  * Store information about a revoked online signing key.
  *
  * @param cls closure
- * @param session a session (can be NULL)
  * @param exchange_pub exchange online signing key that was revoked
  * @param master_sig signature affirming the revocation
  * @return transaction status code
@@ -9901,18 +9351,17 @@ postgres_get_wire_fees (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_insert_signkey_revocation (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ExchangePublicKeyP *exchange_pub,
   const struct TALER_MasterSignatureP *master_sig)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (exchange_pub),
     GNUNET_PQ_query_param_auto_from_type (master_sig),
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_signkey_revocation",
                                              params);
 }
@@ -9922,7 +9371,6 @@ postgres_insert_signkey_revocation (
  * Obtain information about a revoked online signing key.
  *
  * @param cls closure
- * @param session a session (can be NULL)
  * @param exchange_pub exchange online signing key
  * @param[out] master_sig set to signature affirming the revocation (if 
revoked)
  * @return transaction status code
@@ -9930,7 +9378,6 @@ postgres_insert_signkey_revocation (
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_signkey_revocation (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ExchangePublicKeyP *exchange_pub,
   struct TALER_MasterSignatureP *master_sig)
 {
@@ -9945,13 +9392,7 @@ postgres_lookup_signkey_revocation (
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  if (NULL == session)
-    session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "lookup_signkey_revocation",
                                                    params,
                                                    rs);
@@ -9962,7 +9403,6 @@ postgres_lookup_signkey_revocation (
  * Lookup information about current denomination key.
  *
  * @param cls closure
- * @param session a session
  * @param h_denom_pub hash of the denomination public key
  * @param[out] meta set to various meta data about the key
  * @return transaction status code
@@ -9970,7 +9410,6 @@ postgres_lookup_signkey_revocation (
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_denomination_key (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_denom_pub,
   struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta)
 {
@@ -10001,7 +9440,7 @@ postgres_lookup_denomination_key (
     GNUNET_PQ_result_spec_end
   };
 
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "lookup_denomination_key",
                                                    params,
                                                    rs);
@@ -10013,7 +9452,6 @@ postgres_lookup_denomination_key (
  * denomination key by adding the master signature.
  *
  * @param cls closure
- * @param session a session
  * @param h_denom_pub hash of the denomination public key
  * @param denom_pub the actual denomination key
  * @param meta meta data about the denomination
@@ -10023,7 +9461,6 @@ postgres_lookup_denomination_key (
 static enum GNUNET_DB_QueryStatus
 postgres_add_denomination_key (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_denom_pub,
   const struct TALER_DenominationPublicKey *denom_pub,
   const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
@@ -10046,10 +9483,6 @@ postgres_add_denomination_key (
     GNUNET_PQ_query_param_end
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
   /* Sanity check: ensure fees match coin currency */
   GNUNET_assert (GNUNET_YES ==
                  TALER_amount_cmp_currency (&meta->value,
@@ -10063,7 +9496,7 @@ postgres_add_denomination_key (
   GNUNET_assert (GNUNET_YES ==
                  TALER_amount_cmp_currency (&meta->value,
                                             &meta->fee_refund));
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "denomination_insert",
                                              iparams);
 }
@@ -10073,7 +9506,6 @@ postgres_add_denomination_key (
  * Add signing key.
  *
  * @param cls closure
- * @param session a session
  * @param exchange_pub the exchange online signing public key
  * @param meta meta data about @a exchange_pub
  * @param master_sig master signature to add
@@ -10082,7 +9514,6 @@ postgres_add_denomination_key (
 static enum GNUNET_DB_QueryStatus
 postgres_activate_signing_key (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ExchangePublicKeyP *exchange_pub,
   const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
   const struct TALER_MasterSignatureP *master_sig)
@@ -10097,11 +9528,7 @@ postgres_activate_signing_key (
     GNUNET_PQ_query_param_end
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_signkey",
                                              iparams);
 }
@@ -10111,7 +9538,6 @@ postgres_activate_signing_key (
  * Lookup signing key meta data.
  *
  * @param cls closure
- * @param session a session
  * @param exchange_pub the exchange online signing public key
  * @param[out] meta meta data about @a exchange_pub
  * @return transaction status code
@@ -10119,7 +9545,6 @@ postgres_activate_signing_key (
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_signing_key (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct TALER_ExchangePublicKeyP *exchange_pub,
   struct TALER_EXCHANGEDB_SignkeyMetaData *meta)
 {
@@ -10138,11 +9563,7 @@ postgres_lookup_signing_key (
     GNUNET_PQ_result_spec_end
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pg);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "lookup_signing_key",
                                                    params,
                                                    rs);
@@ -10153,7 +9574,6 @@ postgres_lookup_signing_key (
  * Insert information about an auditor auditing a denomination key.
  *
  * @param cls closure
- * @param session a session
  * @param h_denom_pub the audited denomination
  * @param auditor_pub the auditor's key
  * @param auditor_sig signature affirming the auditor's audit activity
@@ -10162,11 +9582,11 @@ postgres_lookup_signing_key (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_auditor_denom_sig (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_denom_pub,
   const struct TALER_AuditorPublicKeyP *auditor_pub,
   const struct TALER_AuditorSignatureP *auditor_sig)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
     GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
@@ -10174,8 +9594,7 @@ postgres_insert_auditor_denom_sig (
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_auditor_denom_sig",
                                              params);
 }
@@ -10185,7 +9604,6 @@ postgres_insert_auditor_denom_sig (
  * Select information about an auditor auditing a denomination key.
  *
  * @param cls closure
- * @param session a session
  * @param h_denom_pub the audited denomination
  * @param auditor_pub the auditor's key
  * @param[out] auditor_sig set to signature affirming the auditor's audit 
activity
@@ -10194,11 +9612,11 @@ postgres_insert_auditor_denom_sig (
 static enum GNUNET_DB_QueryStatus
 postgres_select_auditor_denom_sig (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const struct GNUNET_HashCode *h_denom_pub,
   const struct TALER_AuditorPublicKeyP *auditor_pub,
   struct TALER_AuditorSignatureP *auditor_sig)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (auditor_pub),
     GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
@@ -10210,8 +9628,7 @@ postgres_select_auditor_denom_sig (
     GNUNET_PQ_result_spec_end
   };
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "select_auditor_denom_sig",
                                                    params,
                                                    rs);
@@ -10326,7 +9743,6 @@ wire_fee_by_time_helper (void *cls,
  * succeeds BUT returns an invalid amount for both fees.
  *
  * @param cls closure
- * @param session a session
  * @param wire_method the wire method to lookup fees for
  * @param start_time starting time of fee
  * @param end_time end time of fee
@@ -10341,14 +9757,13 @@ wire_fee_by_time_helper (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_wire_fee_by_time (
   void *cls,
-  struct TALER_EXCHANGEDB_Session *session,
   const char *wire_method,
   struct GNUNET_TIME_Absolute start_time,
   struct GNUNET_TIME_Absolute end_time,
   struct TALER_Amount *wire_fee,
   struct TALER_Amount *closing_fee)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (wire_method),
     GNUNET_PQ_query_param_absolute_time (&start_time),
@@ -10358,14 +9773,10 @@ postgres_lookup_wire_fee_by_time (
   struct WireFeeLookupContext wlc = {
     .wire_fee = wire_fee,
     .closing_fee = closing_fee,
-    .pg = pc,
+    .pg = pg,
   };
 
-  if (NULL == session)
-    session = postgres_get_session (pc);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                                "lookup_wire_fee_by_time",
                                                params,
                                                &wire_fee_by_time_helper,
@@ -10378,7 +9789,6 @@ postgres_lookup_wire_fee_by_time (
  * exchange-auditor database replication.
  *
  * @param cls closure
- * @param session a session
  * @param table table for which we should return the serial
  * @param[out] serial latest serial number in use
  * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if
@@ -10386,10 +9796,10 @@ postgres_lookup_wire_fee_by_time (
  */
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_serial_by_table (void *cls,
-                                 struct TALER_EXCHANGEDB_Session *session,
                                  enum TALER_EXCHANGEDB_ReplicatedTable table,
                                  uint64_t *serial)
 {
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_end
   };
@@ -10470,8 +9880,7 @@ postgres_lookup_serial_by_table (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  (void) cls;
-  return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    statement,
                                                    params,
                                                    rs);
@@ -10513,7 +9922,6 @@ struct LookupRecordsByTableContext
  * exchange-auditor database replication.
  *
  * @param cls closure
- * @param session a session
  * @param table table for which we should return the serial
  * @param serial largest serial number to exclude
  * @param cb function to call on the records
@@ -10523,19 +9931,18 @@ struct LookupRecordsByTableContext
  */
 static enum GNUNET_DB_QueryStatus
 postgres_lookup_records_by_table (void *cls,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   enum TALER_EXCHANGEDB_ReplicatedTable table,
                                   uint64_t serial,
                                   TALER_EXCHANGEDB_ReplicationCallback cb,
                                   void *cb_cls)
 {
-  struct PostgresClosure *pc = cls;
+  struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&serial),
     GNUNET_PQ_query_param_end
   };
   struct LookupRecordsByTableContext ctx = {
-    .pg = pc,
+    .pg = pg,
     .cb = cb,
     .cb_cls = cb_cls
   };
@@ -10634,8 +10041,7 @@ postgres_lookup_records_by_table (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  (void) cls;
-  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                              statement,
                                              params,
                                              rh,
@@ -10652,13 +10058,11 @@ postgres_lookup_records_by_table (void *cls,
  * Signature of helper functions of #postgres_insert_records_by_table.
  *
  * @param pg plugin context
- * @param session database session
  * @param td record to insert
  * @return transaction status code
  */
 typedef enum GNUNET_DB_QueryStatus
 (*InsertRecordCallback)(struct PostgresClosure *pg,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_EXCHANGEDB_TableData *td);
 
 
@@ -10670,14 +10074,12 @@ typedef enum GNUNET_DB_QueryStatus
  * replication.
  *
  * @param cls closure
- * @param session a session
  * @param td table data to insert
  * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
  *         @e table in @a tr is not supported
  */
 static enum GNUNET_DB_QueryStatus
 postgres_insert_records_by_table (void *cls,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   const struct TALER_EXCHANGEDB_TableData *td)
 {
   struct PostgresClosure *pg = cls;
@@ -10753,14 +10155,13 @@ postgres_insert_records_by_table (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   return rh (pg,
-             session,
              td);
 }
 
 
 /**
  * Function called to grab a work shard on an operation @a op. Runs in its
- * own transaction (hence no session provided).
+ * own transaction.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
  * @param job_name name of the operation to grab a word shard for
@@ -10778,16 +10179,12 @@ postgres_begin_shard (void *cls,
                       uint64_t *start_row,
                       uint64_t *end_row)
 {
-  struct TALER_EXCHANGEDB_Session *session;
+  struct PostgresClosure *pg = cls;
 
-  session = postgres_get_session (cls);
-  if (NULL == session)
-    return GNUNET_DB_STATUS_HARD_ERROR;
   for (unsigned int retries = 0; retries<3; retries++)
   {
     if (GNUNET_OK !=
-        postgres_start (cls,
-                        session,
+        postgres_start (pg,
                         "begin_shard"))
     {
       GNUNET_break (0);
@@ -10812,7 +10209,7 @@ postgres_begin_shard (void *cls,
 
       past = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (),
                                             delay);
-      qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+      qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                      "get_open_shard",
                                                      params,
                                                      rs);
@@ -10820,12 +10217,10 @@ postgres_begin_shard (void *cls,
       {
       case GNUNET_DB_STATUS_HARD_ERROR:
         GNUNET_break (0);
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         return qs;
       case GNUNET_DB_STATUS_SOFT_ERROR:
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         continue;
       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
         {
@@ -10840,26 +10235,23 @@ postgres_begin_shard (void *cls,
           };
 
           now = GNUNET_TIME_absolute_get ();
-          qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+          qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                    "reclaim_shard",
                                                    params);
           switch (qs)
           {
           case GNUNET_DB_STATUS_HARD_ERROR:
             GNUNET_break (0);
-            postgres_rollback (cls,
-                               session);
+            postgres_rollback (pg);
             return qs;
           case GNUNET_DB_STATUS_SOFT_ERROR:
-            postgres_rollback (cls,
-                               session);
+            postgres_rollback (pg);
             continue;
           case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
             goto commit;
           case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
             GNUNET_break (0); /* logic error, should be impossible */
-            postgres_rollback (cls,
-                               session);
+            postgres_rollback (pg);
             return GNUNET_DB_STATUS_HARD_ERROR;
           }
         }
@@ -10882,7 +10274,7 @@ postgres_begin_shard (void *cls,
         GNUNET_PQ_result_spec_end
       };
 
-      qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+      qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                      "get_last_shard",
                                                      params,
                                                      rs);
@@ -10890,12 +10282,10 @@ postgres_begin_shard (void *cls,
       {
       case GNUNET_DB_STATUS_HARD_ERROR:
         GNUNET_break (0);
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         return qs;
       case GNUNET_DB_STATUS_SOFT_ERROR:
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         continue;
       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
         break;
@@ -10923,19 +10313,17 @@ postgres_begin_shard (void *cls,
                   "Trying to claim shard %llu-%llu\n",
                   (unsigned long long) *start_row,
                   (unsigned long long) *end_row);
-      qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                                "claim_next_shard",
                                                params);
       switch (qs)
       {
       case GNUNET_DB_STATUS_HARD_ERROR:
         GNUNET_break (0);
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         return qs;
       case GNUNET_DB_STATUS_SOFT_ERROR:
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         continue;
       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
         /* continued below */
@@ -10943,8 +10331,7 @@ postgres_begin_shard (void *cls,
       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
         /* someone else got this shard already,
            try again */
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         continue;
       }
     } /* claim_next_shard */
@@ -10954,18 +10341,15 @@ commit:
     {
       enum GNUNET_DB_QueryStatus qs;
 
-      qs = postgres_commit (cls,
-                            session);
+      qs = postgres_commit (pg);
       switch (qs)
       {
       case GNUNET_DB_STATUS_HARD_ERROR:
         GNUNET_break (0);
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         return qs;
       case GNUNET_DB_STATUS_SOFT_ERROR:
-        postgres_rollback (cls,
-                           session);
+        postgres_rollback (pg);
         continue;
       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
@@ -10981,7 +10365,6 @@ commit:
  * Function called to persist that work on a shard was completed.
  *
  * @param cls the @e cls of this struct with the plugin-specific state
- * @param session a session
  * @param job_name name of the operation to grab a word shard for
  * @param start_row inclusive start row of the shard
  * @param end_row exclusive end row of the shard
@@ -10989,11 +10372,12 @@ commit:
  */
 enum GNUNET_DB_QueryStatus
 postgres_complete_shard (void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const char *job_name,
                          uint64_t start_row,
                          uint64_t end_row)
 {
+  struct PostgresClosure *pg = cls;
+
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (job_name),
     GNUNET_PQ_query_param_uint64 (&start_row),
@@ -11001,12 +10385,11 @@ postgres_complete_shard (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Completing shard %llu-%llu\n",
               (unsigned long long) start_row,
               (unsigned long long) end_row);
-  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "complete_shard",
                                              params);
 }
@@ -11028,9 +10411,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
 
   pg = GNUNET_new (struct PostgresClosure);
   pg->cfg = cfg;
-  pg->event_heap = GNUNET_CONTAINER_heap_create (
-    GNUNET_CONTAINER_HEAP_ORDER_MIN);
-  pg->main_self = pthread_self (); /* loaded while single-threaded! */
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg,
                                                "exchangedb-postgres",
@@ -11043,14 +10423,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     GNUNET_free (pg);
     return NULL;
   }
-  if (0 != pthread_key_create (&pg->db_conn_threadlocal,
-                               &db_conn_destroy))
-  {
-    TALER_LOG_ERROR ("Cannot create pthread key.\n");
-    GNUNET_free (pg->sql_dir);
-    GNUNET_free (pg);
-    return NULL;
-  }
   if ( (GNUNET_OK !=
         GNUNET_CONFIGURATION_get_value_time (cfg,
                                              "exchangedb",
@@ -11078,39 +10450,18 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     GNUNET_free (pg);
     return NULL;
   }
+  if (GNUNET_OK !=
+      internal_setup (pg,
+                      true))
   {
-    struct TALER_EXCHANGEDB_Session *session;
-
-    session = internal_get_session (pg,
-                                    true);
-    if (NULL == session)
-    {
-      GNUNET_free (pg->currency);
-      GNUNET_free (pg->sql_dir);
-      GNUNET_free (pg);
-      return NULL;
-    }
-    pg->event_fd = eventfd (0, 0);
-    if (-1 == pg->event_fd)
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                           "eventfd");
-      GNUNET_free (pg->currency);
-      GNUNET_free (pg->sql_dir);
-      GNUNET_free (pg);
-      return NULL;
-    }
-    GNUNET_assert (0 ==
-                   pthread_mutex_init (&pg->event_lock,
-                                       NULL));
-    GNUNET_PQ_event_set_socket_callback (session->conn,
-                                         &pq_socket_cb,
-                                         pg);
+    GNUNET_free (pg->currency);
+    GNUNET_free (pg->sql_dir);
+    GNUNET_free (pg);
+    return NULL;
   }
 
   plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin);
   plugin->cls = pg;
-  plugin->get_session = &postgres_get_session;
   plugin->drop_tables = &postgres_drop_tables;
   plugin->create_tables = &postgres_create_tables;
   plugin->start = &postgres_start;
@@ -11272,14 +10623,8 @@ libtaler_plugin_exchangedb_postgres_done (void *cls)
   struct TALER_EXCHANGEDB_Plugin *plugin = cls;
   struct PostgresClosure *pg = plugin->cls;
 
-  /* If we launched a session for the main thread,
-     kill it here before we unload */
-  GNUNET_assert (0 == pg->listener_count);
-  db_conn_destroy (pg->main_session);
-  GNUNET_break (0 ==
-                close (pg->event_fd));
-  pthread_mutex_destroy (&pg->event_lock);
-  GNUNET_CONTAINER_heap_destroy (pg->event_heap);
+  if (NULL != pg->conn)
+    GNUNET_PQ_disconnect (pg->conn);
   GNUNET_free (pg->sql_dir);
   GNUNET_free (pg->currency);
   GNUNET_free (pg);
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 65061030..1cccb23c 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -95,8 +95,6 @@ mark_prepare_cb (void *cls,
                  const char *buf,
                  size_t buf_size)
 {
-  struct TALER_EXCHANGEDB_Session *session = cls;
-
   GNUNET_assert (11 == buf_size);
   GNUNET_assert (0 == strcasecmp (wire_method,
                                   "testcase"));
@@ -105,7 +103,6 @@ mark_prepare_cb (void *cls,
                               buf_size));
   GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
                 plugin->wire_prepare_data_mark_finished (plugin->cls,
-                                                         session,
                                                          rowid));
 }
 
@@ -113,31 +110,26 @@ mark_prepare_cb (void *cls,
 /**
  * Test API relating to persisting the wire plugins preparation data.
  *
- * @param session database session to use for the test
  * @return #GNUNET_OK on success
  */
 static int
-test_wire_prepare (struct TALER_EXCHANGEDB_Session *session)
+test_wire_prepare (void)
 {
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->wire_prepare_data_get (plugin->cls,
-                                         session,
                                          &dead_prepare_cb,
                                          NULL));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->wire_prepare_data_insert (plugin->cls,
-                                            session,
                                             "testcase",
                                             "hello world",
                                             11));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->wire_prepare_data_get (plugin->cls,
-                                         session,
                                          &mark_prepare_cb,
-                                         session));
+                                         NULL));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->wire_prepare_data_get (plugin->cls,
-                                         session,
                                          &dead_prepare_cb,
                                          NULL));
   return GNUNET_OK;
@@ -149,7 +141,6 @@ drop:
 /**
  * Checks if the given reserve has the given amount of balance and expiry
  *
- * @param session the database connection
  * @param pub the public key of the reserve
  * @param value balance value
  * @param fraction balance fraction
@@ -158,8 +149,7 @@ drop:
  *           as the given parameters; #GNUNET_SYSERR if not
  */
 static int
-check_reserve (struct TALER_EXCHANGEDB_Session *session,
-               const struct TALER_ReservePublicKeyP *pub,
+check_reserve (const struct TALER_ReservePublicKeyP *pub,
                uint64_t value,
                uint32_t fraction,
                const char *currency)
@@ -169,7 +159,6 @@ check_reserve (struct TALER_EXCHANGEDB_Session *session,
   reserve.pub = *pub;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->reserves_get (plugin->cls,
-                                session,
                                 &reserve));
   FAILIF (value != reserve.balance.value);
   FAILIF (fraction != reserve.balance.fraction);
@@ -206,7 +195,6 @@ destroy_denom_key_pair (struct DenomKeyPair *dkp)
  * Create a denominaiton key pair by registering the denomination in the DB.
  *
  * @param size the size of the denomination key
- * @param session the DB session
  * @param now time to use for key generation, legal expiration will be 3h 
later.
  * @param fee_withdraw withdraw fee to use
  * @param fee_deposit deposit fee to use
@@ -216,7 +204,6 @@ destroy_denom_key_pair (struct DenomKeyPair *dkp)
  */
 static struct DenomKeyPair *
 create_denom_key_pair (unsigned int size,
-                       struct TALER_EXCHANGEDB_Session *session,
                        struct GNUNET_TIME_Absolute now,
                        const struct TALER_Amount *value,
                        const struct TALER_Amount *fee_withdraw,
@@ -269,7 +256,6 @@ create_denom_key_pair (unsigned int size,
     TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       plugin->insert_denomination_info (plugin->cls,
-                                        session,
                                         &dki.denom_pub,
                                         &dki.issue))
   {
@@ -279,7 +265,6 @@ create_denom_key_pair (unsigned int size,
   }
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       plugin->get_denomination_info (plugin->cls,
-                                     session,
                                      &dki.issue.properties.denom_hash,
                                      &issue2))
   {
@@ -502,12 +487,10 @@ handle_link_data_cb (void *cls,
 /**
  * Function to test melting of coins as part of a refresh session
  *
- * @param session the database session
- * @param refresh_session the refresh session
  * @return #GNUNET_OK if everything went well; #GNUNET_SYSERR if not
  */
 static int
-test_melting (struct TALER_EXCHANGEDB_Session *session)
+test_melting (void)
 {
   struct TALER_EXCHANGEDB_Refresh refresh_session;
   struct TALER_EXCHANGEDB_Melt ret_refresh_session;
@@ -528,7 +511,6 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
   now = GNUNET_TIME_absolute_get ();
   GNUNET_TIME_round_abs (&now);
   dkp = create_denom_key_pair (512,
-                               session,
                                now,
                                &value,
                                &fee_withdraw,
@@ -556,20 +538,16 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
   /* test insert_melt & get_melt */
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->get_melt (plugin->cls,
-                            session,
                             &refresh_session.rc,
                             &ret_refresh_session));
   FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
-                                     session,
                                      &refresh_session.coin));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_melt (plugin->cls,
-                               session,
                                &refresh_session));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_melt (plugin->cls,
-                            session,
                             &refresh_session.rc,
                             &ret_refresh_session));
   FAILIF (refresh_session.noreveal_index !=
@@ -597,7 +575,6 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
   auditor_row_cnt = 0;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_refreshes_above_serial_id (plugin->cls,
-                                                    session,
                                                     0,
                                                     &audit_refresh_session_cb,
                                                     NULL));
@@ -619,7 +596,6 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
     now = GNUNET_TIME_absolute_get ();
     GNUNET_TIME_round_abs (&now);
     new_dkp[cnt] = create_denom_key_pair (1024,
-                                          session,
                                           now,
                                           &value,
                                           &fee_withdraw,
@@ -646,13 +622,11 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
   RND_BLK (&tpub);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->get_refresh_reveal (plugin->cls,
-                                      session,
                                       &refresh_session.rc,
                                       &never_called_cb,
                                       NULL));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_refresh_reveal (plugin->cls,
-                                         session,
                                          &refresh_session.rc,
                                          MELT_NEW_COINS,
                                          revealed_coins,
@@ -661,14 +635,12 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
                                          &tpub));
   FAILIF (0 >=
           plugin->get_refresh_reveal (plugin->cls,
-                                      session,
                                       &refresh_session.rc,
                                       &check_refresh_reveal_cb,
                                       NULL));
 
 
   qs = plugin->get_link_data (plugin->cls,
-                              session,
                               &refresh_session.coin.coin_pub,
                               &handle_link_data_cb,
                               NULL);
@@ -679,7 +651,6 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
     enum GNUNET_DB_QueryStatus qs;
 
     qs = plugin->get_coin_transactions (plugin->cls,
-                                        session,
                                         &refresh_session.coin.coin_pub,
                                         GNUNET_YES,
                                         &tl);
@@ -1085,11 +1056,10 @@ audit_reserve_out_cb (void *cls,
 /**
  * Test garbage collection.
  *
- * @param session DB session to use
  * @return #GNUNET_OK on success
  */
 static int
-test_gc (struct TALER_EXCHANGEDB_Session *session)
+test_gc (void)
 {
   struct DenomKeyPair *dkp;
   struct GNUNET_TIME_Absolute now;
@@ -1104,7 +1074,6 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)
                                           GNUNET_TIME_UNIT_HOURS,
                                           4));
   dkp = create_denom_key_pair (1024,
-                               session,
                                past,
                                &value,
                                &fee_withdraw,
@@ -1124,7 +1093,6 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)
 
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
       plugin->get_denomination_info (plugin->cls,
-                                     session,
                                      &denom_hash,
                                      &issue2))
   {
@@ -1140,11 +1108,10 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)
 /**
  * Test wire fee storage.
  *
- * @param session DB session to use
  * @return #GNUNET_OK on success
  */
 static int
-test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
+test_wire_fees (void)
 {
   struct GNUNET_TIME_Absolute start_date;
   struct GNUNET_TIME_Absolute end_date;
@@ -1172,7 +1139,6 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
                               sizeof (master_sig));
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       plugin->insert_wire_fee (plugin->cls,
-                               session,
                                "wire-method",
                                start_date,
                                end_date,
@@ -1185,7 +1151,6 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
       plugin->insert_wire_fee (plugin->cls,
-                               session,
                                "wire-method",
                                start_date,
                                end_date,
@@ -1200,7 +1165,6 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
      half-open interval [start_date,end_date) */
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
       plugin->get_wire_fee (plugin->cls,
-                            session,
                             "wire-method",
                             end_date,
                             &sd,
@@ -1214,7 +1178,6 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
   }
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       plugin->get_wire_fee (plugin->cls,
-                            session,
                             "wire-method",
                             start_date,
                             &sd,
@@ -1279,12 +1242,10 @@ audit_wire_cb (void *cls,
 /**
  * Test API relating to wire_out handling.
  *
- * @param session database session to use for the test
  * @return #GNUNET_OK on success
  */
 static int
-test_wire_out (struct TALER_EXCHANGEDB_Session *session,
-               const struct TALER_EXCHANGEDB_Deposit *deposit)
+test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit)
 {
   auditor_row_cnt = 0;
   memset (&wire_out_wtid,
@@ -1300,8 +1261,7 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
      the aggregation table, so we need to start the special
      transaction where this is allowed... */
   FAILIF (GNUNET_OK !=
-          plugin->start_deferred_wire_out (plugin->cls,
-                                           session));
+          plugin->start_deferred_wire_out (plugin->cls));
 
   /* setup values for wire transfer aggregation data */
   merchant_pub_wt = deposit->merchant_pub;
@@ -1317,7 +1277,6 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
                                         &coin_fee_wt));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->lookup_wire_transfer (plugin->cls,
-                                        session,
                                         &wire_out_wtid,
                                         &cb_wt_never,
                                         NULL));
@@ -1328,7 +1287,6 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
     h_contract_terms_wt2.bits[0]++;
     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
             plugin->lookup_transfer_by_deposit (plugin->cls,
-                                                session,
                                                 &h_contract_terms_wt2,
                                                 &h_wire_wt,
                                                 &coin_pub_wt,
@@ -1339,7 +1297,6 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
   /* insert WT data */
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_aggregation_tracking (plugin->cls,
-                                               session,
                                                &wire_out_wtid,
                                                deposit_rowid));
 
@@ -1355,7 +1312,6 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
                                "this-is-my-salt"));
     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
         plugin->store_wire_transfer_out (plugin->cls,
-                                         session,
                                          wire_out_date,
                                          &wire_out_wtid,
                                          wire_out_account,
@@ -1369,18 +1325,15 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
   }
   /* And now the commit should still succeed! */
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-          plugin->commit (plugin->cls,
-                          session));
+          plugin->commit (plugin->cls));
 
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->lookup_wire_transfer (plugin->cls,
-                                        session,
                                         &wire_out_wtid,
                                         &cb_wt_check,
                                         &cb_wt_never));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->lookup_transfer_by_deposit (plugin->cls,
-                                              session,
                                               &h_contract_terms_wt,
                                               &h_wire_wt,
                                               &coin_pub_wt,
@@ -1389,7 +1342,6 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
                                               &cb_wtid_never));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_wire_out_above_serial_id (plugin->cls,
-                                                   session,
                                                    0,
                                                    &audit_wire_cb,
                                                    NULL));
@@ -1536,7 +1488,6 @@ static void
 run (void *cls)
 {
   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
-  struct TALER_EXCHANGEDB_Session *session;
   struct TALER_CoinSpendSignatureP coin_sig;
   struct GNUNET_TIME_Absolute deadline;
   struct TALER_DenominationBlindingKeyP coin_blind;
@@ -1566,7 +1517,6 @@ run (void *cls)
 
   dkp = NULL;
   rh = NULL;
-  session = NULL;
   deposit.coin.denom_sig.rsa_signature = NULL;
   wire = GNUNET_JSON_PACK (
     GNUNET_JSON_pack_string ("payto_uri",
@@ -1588,22 +1538,14 @@ run (void *cls)
     result = 77;
     goto drop;
   }
-  if (NULL ==
-      (session = plugin->get_session (plugin->cls)))
-  {
-    result = 77;
-    goto drop;
-  }
-
+  plugin->preflight (plugin->cls);
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-1"));
 
   /* test DB is empty */
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->select_recoup_above_serial_id (plugin->cls,
-                                                 session,
                                                  0,
                                                  &recoup_cb,
                                                  NULL));
@@ -1630,14 +1572,12 @@ run (void *cls)
   result = 4;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->get_latest_reserve_in_reference (plugin->cls,
-                                                   session,
                                                    "exchange-account-1",
                                                    &rr));
   now = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&now);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->reserves_in_insert (plugin->cls,
-                                      session,
                                       &reserve_pub,
                                       &value,
                                       now,
@@ -1646,13 +1586,11 @@ run (void *cls)
                                       4));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_latest_reserve_in_reference (plugin->cls,
-                                                   session,
                                                    "exchange-account-1",
                                                    &rr));
   FAILIF (4 != rr);
   FAILIF (GNUNET_OK !=
-          check_reserve (session,
-                         &reserve_pub,
+          check_reserve (&reserve_pub,
                          value.value,
                          value.fraction,
                          value.currency));
@@ -1660,7 +1598,6 @@ run (void *cls)
   (void) GNUNET_TIME_round_abs (&now);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->reserves_in_insert (plugin->cls,
-                                      session,
                                       &reserve_pub,
                                       &value,
                                       now,
@@ -1669,18 +1606,15 @@ run (void *cls)
                                       5));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_latest_reserve_in_reference (plugin->cls,
-                                                   session,
                                                    "exchange-account-1",
                                                    &rr));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_latest_reserve_in_reference (plugin->cls,
-                                                   session,
                                                    "exchange-account-1",
                                                    &rr));
   FAILIF (5 != rr);
   FAILIF (GNUNET_OK !=
-          check_reserve (session,
-                         &reserve_pub,
+          check_reserve (&reserve_pub,
                          value.value * 2,
                          value.fraction * 2,
                          value.currency));
@@ -1688,7 +1622,6 @@ run (void *cls)
   now = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&now);
   dkp = create_denom_key_pair (1024,
-                               session,
                                now,
                                &value,
                                &fee_withdraw,
@@ -1710,18 +1643,15 @@ run (void *cls)
                  TALER_amount_set_zero (CURRENCY, &cbc.withdraw_fee));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_withdraw_info (plugin->cls,
-                                        session,
                                         &cbc));
   FAILIF (GNUNET_OK !=
-          check_reserve (session,
-                         &reserve_pub,
+          check_reserve (&reserve_pub,
                          value.value,
                          value.fraction,
                          value.currency));
 
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_reserve_by_h_blind (plugin->cls,
-                                          session,
                                           &cbc.h_coin_envelope,
                                           &reserve_pub2));
   FAILIF (0 != GNUNET_memcmp (&reserve_pub,
@@ -1729,7 +1659,6 @@ run (void *cls)
 
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_withdraw_info (plugin->cls,
-                                     session,
                                      &cbc.h_coin_envelope,
                                      &cbc2));
   FAILIF (0 != GNUNET_memcmp (&cbc2.reserve_sig, &cbc.reserve_sig));
@@ -1751,7 +1680,6 @@ run (void *cls)
   (void) GNUNET_TIME_round_abs (&deadline);
   FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
-                                     session,
                                      &deposit.coin));
   {
     struct TALER_EXCHANGEDB_Reserve pre_reserve;
@@ -1761,11 +1689,9 @@ run (void *cls)
     pre_reserve.pub = reserve_pub;
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->reserves_get (plugin->cls,
-                                  session,
                                   &pre_reserve));
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->insert_recoup_request (plugin->cls,
-                                           session,
                                            &reserve_pub,
                                            &deposit.coin,
                                            &coin_sig,
@@ -1776,7 +1702,6 @@ run (void *cls)
     post_reserve.pub = reserve_pub;
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->reserves_get (plugin->cls,
-                                  session,
                                   &post_reserve));
     FAILIF (0 >=
             TALER_amount_subtract (&delta,
@@ -1788,7 +1713,6 @@ run (void *cls)
   }
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_recoup_above_serial_id (plugin->cls,
-                                                 session,
                                                  0,
                                                  &recoup_cb,
                                                  &coin_blind));
@@ -1804,7 +1728,6 @@ run (void *cls)
   (void) GNUNET_TIME_round_abs (&now);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_reserve_closed (plugin->cls,
-                                         session,
                                          &reserve_pub,
                                          now,
                                          sndr,
@@ -1812,15 +1735,13 @@ run (void *cls)
                                          &amount_with_fee,
                                          &fee_closing));
   FAILIF (GNUNET_OK !=
-          check_reserve (session,
-                         &reserve_pub,
+          check_reserve (&reserve_pub,
                          0,
                          0,
                          value.currency));
 
   result = 7;
   qs = plugin->get_reserve_history (plugin->cls,
-                                    session,
                                     &reserve_pub,
                                     &rh);
   FAILIF (0 > qs);
@@ -1891,13 +1812,11 @@ run (void *cls)
   auditor_row_cnt = 0;
   FAILIF (0 >=
           plugin->select_reserves_in_above_serial_id (plugin->cls,
-                                                      session,
                                                       0,
                                                       &audit_reserve_in_cb,
                                                       NULL));
   FAILIF (0 >=
           plugin->select_withdrawals_above_serial_id (plugin->cls,
-                                                      session,
                                                       0,
                                                       &audit_reserve_out_cb,
                                                       NULL));
@@ -1926,7 +1845,6 @@ run (void *cls)
   result = 8;
   FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
-                                     session,
                                      &deposit.coin));
   {
     struct GNUNET_TIME_Absolute now;
@@ -1937,12 +1855,10 @@ run (void *cls)
     GNUNET_TIME_round_abs (&now);
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->insert_deposit (plugin->cls,
-                                    session,
                                     now,
                                     &deposit));
     FAILIF (1 !=
             plugin->have_deposit (plugin->cls,
-                                  session,
                                   &deposit,
                                   GNUNET_YES,
                                   &deposit_fee,
@@ -1959,7 +1875,6 @@ run (void *cls)
                                           GNUNET_TIME_UNIT_SECONDS);
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->select_deposits_missing_wire (plugin->cls,
-                                                  session,
                                                   start_range,
                                                   end_range,
                                                   &wire_missing_cb,
@@ -1969,7 +1884,6 @@ run (void *cls)
   auditor_row_cnt = 0;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_deposits_above_serial_id (plugin->cls,
-                                                   session,
                                                    0,
                                                    &audit_deposit_cb,
                                                    NULL));
@@ -1977,7 +1891,6 @@ run (void *cls)
   result = 9;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->iterate_matching_deposits (plugin->cls,
-                                             session,
                                              &deposit.h_wire,
                                              &deposit.merchant_pub,
                                              &matching_deposit_cb,
@@ -1986,53 +1899,41 @@ run (void *cls)
   sleep (2); /* giv deposit time to be ready */
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_ready_deposit (plugin->cls,
-                                     session,
                                      &deposit_cb,
                                      &deposit));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-          plugin->commit (plugin->cls,
-                          session));
+          plugin->commit (plugin->cls));
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-2"));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->mark_deposit_tiny (plugin->cls,
-                                     session,
                                      deposit_rowid));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->get_ready_deposit (plugin->cls,
-                                     session,
                                      &deposit_cb,
                                      &deposit));
-  plugin->rollback (plugin->cls,
-                    session);
+  plugin->rollback (plugin->cls);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->get_ready_deposit (plugin->cls,
-                                     session,
                                      &deposit_cb,
                                      &deposit));
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-3"));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->test_deposit_done (plugin->cls,
-                                     session,
                                      &deposit.coin.coin_pub,
                                      &deposit.merchant_pub,
                                      &deposit.h_contract_terms,
                                      &deposit.h_wire));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->mark_deposit_done (plugin->cls,
-                                     session,
                                      deposit_rowid));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-          plugin->commit (plugin->cls,
-                          session));
+          plugin->commit (plugin->cls));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->test_deposit_done (plugin->cls,
-                                     session,
                                      &deposit.coin.coin_pub,
                                      &deposit.merchant_pub,
                                      &deposit.h_contract_terms,
@@ -2042,7 +1943,6 @@ run (void *cls)
   deposit2 = deposit;
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-2"));
   RND_BLK (&deposit2.merchant_pub); /* should fail if merchant is different */
   {
@@ -2051,7 +1951,6 @@ run (void *cls)
 
     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
             plugin->have_deposit (plugin->cls,
-                                  session,
                                   &deposit2,
                                   GNUNET_YES,
                                   &deposit_fee,
@@ -2060,17 +1959,15 @@ run (void *cls)
     RND_BLK (&deposit2.coin.coin_pub); /* should fail if coin is different */
     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
             plugin->have_deposit (plugin->cls,
-                                  session,
                                   &deposit2,
                                   GNUNET_YES,
                                   &deposit_fee,
                                   &r));
   }
   FAILIF (GNUNET_OK !=
-          test_melting (session));
+          test_melting ());
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-          plugin->commit (plugin->cls,
-                          session));
+          plugin->commit (plugin->cls));
 
 
   /* test insert_refund! */
@@ -2085,11 +1982,9 @@ run (void *cls)
   refund.details.refund_fee = fee_refund;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_refund (plugin->cls,
-                                 session,
                                  &refund));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_refunds_by_coin (plugin->cls,
-                                          session,
                                           &refund.coin.coin_pub,
                                           &refund.details.merchant_pub,
                                           &refund.details.h_contract_terms,
@@ -2100,30 +1995,22 @@ run (void *cls)
   RND_BLK (&master_sig);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_denomination_revocation (plugin->cls,
-                                                  session,
                                                   &dkp_pub_hash,
                                                   &master_sig));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-          plugin->commit (plugin->cls,
-                          session));
-  plugin->preflight (plugin->cls,
-                     session);
+          plugin->commit (plugin->cls));
+  plugin->preflight (plugin->cls);
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-4"));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->insert_denomination_revocation (plugin->cls,
-                                                  session,
                                                   &dkp_pub_hash,
                                                   &master_sig));
-  plugin->rollback (plugin->cls,
-                    session);
-  plugin->preflight (plugin->cls,
-                     session);
+  plugin->rollback (plugin->cls);
+  plugin->preflight (plugin->cls);
   FAILIF (GNUNET_OK !=
           plugin->start (plugin->cls,
-                         session,
                          "test-5"));
   {
     struct TALER_MasterSignatureP msig;
@@ -2131,7 +2018,6 @@ run (void *cls)
 
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->get_denomination_revocation (plugin->cls,
-                                                 session,
                                                  &dkp_pub_hash,
                                                  &msig,
                                                  &rev_rowid));
@@ -2144,7 +2030,6 @@ run (void *cls)
   RND_BLK (&coin_blind);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_recoup_request (plugin->cls,
-                                         session,
                                          &reserve_pub,
                                          &deposit.coin,
                                          &coin_sig,
@@ -2156,14 +2041,12 @@ run (void *cls)
   auditor_row_cnt = 0;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->select_refunds_above_serial_id (plugin->cls,
-                                                  session,
                                                   0,
                                                   &audit_refund_cb,
                                                   NULL));
 
   FAILIF (1 != auditor_row_cnt);
   qs = plugin->get_coin_transactions (plugin->cls,
-                                      session,
                                       &refund.coin.coin_pub,
                                       GNUNET_YES,
                                       &tl);
@@ -2262,28 +2145,23 @@ run (void *cls)
   plugin->free_coin_transaction_list (plugin->cls,
                                       tl);
 
-  plugin->rollback (plugin->cls,
-                    session);
+  plugin->rollback (plugin->cls);
   FAILIF (GNUNET_OK !=
-          test_wire_prepare (session));
+          test_wire_prepare ());
   FAILIF (GNUNET_OK !=
-          test_wire_out (session,
-                         &deposit));
+          test_wire_out (&deposit));
   FAILIF (GNUNET_OK !=
-          test_gc (session));
+          test_gc ());
   FAILIF (GNUNET_OK !=
-          test_wire_fees (session));
+          test_wire_fees ());
 
-  plugin->preflight (plugin->cls,
-                     session);
+  plugin->preflight (plugin->cls);
 
   result = 0;
 
 drop:
-  if ( (0 != result) &&
-       (NULL != session) )
-    plugin->rollback (plugin->cls,
-                      session);
+  if (0 != result)
+    plugin->rollback (plugin->cls);
   if (NULL != rh)
     plugin->free_reserve_history (plugin->cls,
                                   rh);
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 3fc5f353..f95577d0 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2020 Taler Systems SA
+  Copyright (C) 2014-2021 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -1164,6 +1164,8 @@ typedef void
  *
  * @param exchange the exchange handle; the exchange must be ready to operate
  * @param reserve_pub public key of the reserve to inspect
+ * @param timeout how long to wait for an affirmative reply
+ *        (enables long polling if the reserve does not yet exist)
  * @param cb the callback to call when a reply for this request is available
  * @param cb_cls closure for the above callback
  * @return a handle for this request; NULL if the inputs are invalid (i.e.
@@ -1173,6 +1175,7 @@ struct TALER_EXCHANGE_ReservesGetHandle *
 TALER_EXCHANGE_reserves_get (
   struct TALER_EXCHANGE_Handle *exchange,
   const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct GNUNET_TIME_Relative timeout,
   TALER_EXCHANGE_ReservesGetCallback cb,
   void *cb_cls);
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 4cf6514f..eac7bf75 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -92,12 +92,6 @@ struct TALER_ReserveEventP
 
 GNUNET_NETWORK_STRUCT_END
 
-/**
- * Event registration record.
- */
-struct TALER_EXCHANGEDB_EventHandler;
-
-
 /**
  * Meta data about an exchange online signing key.
  */
@@ -1448,12 +1442,6 @@ struct TALER_EXCHANGEDB_TransactionList
 };
 
 
-/**
- * @brief Handle for a database session (per-thread, for transactions).
- */
-struct TALER_EXCHANGEDB_Session;
-
-
 /**
  * Function called with details about deposits that have been made,
  * with the goal of executing the corresponding wire transaction.
@@ -2071,16 +2059,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   char *library_name;
 
-  /**
-   * Get the thread-local (!) database-handle.
-   * Connect to the db if the connection does not exist yet.
-   *
-   * @param cls the @e cls of this struct with the plugin-specific state
-   * @returns the database connection, or NULL on error
-   */
-  struct TALER_EXCHANGEDB_Session *
-  (*get_session) (void *cls);
-
 
   /**
    * Drop the Taler tables.  This should only be used in testcases.
@@ -2106,14 +2084,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Start a transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @param name unique name identifying the transaction (for debugging),
    *             must point to a constant
    * @return #GNUNET_OK on success
    */
   int
   (*start) (void *cls,
-            struct TALER_EXCHANGEDB_Session *session,
             const char *name);
 
 
@@ -2121,14 +2097,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Start a READ COMMITTED transaction.
    *
    * @param cls the `struct PostgresClosure` with the plugin-specific state
-   * @param session the database connection
    * @param name unique name identifying the transaction (for debugging)
    *             must point to a constant
    * @return #GNUNET_OK on success
    */
   int
   (*start_read_committed)(void *cls,
-                          struct TALER_EXCHANGEDB_Session *session,
                           const char *name);
 
 
@@ -2136,12 +2110,10 @@ struct TALER_EXCHANGEDB_Plugin
    * Commit a transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
-  (*commit)(void *cls,
-            struct TALER_EXCHANGEDB_Session *session);
+  (*commit)(void *cls);
 
 
   /**
@@ -2150,22 +2122,21 @@ struct TALER_EXCHANGEDB_Plugin
    * Does not return anything, as we will continue regardless of the outcome.
    *
    * @param cls the `struct PostgresClosure` with the plugin-specific state
-   * @param session the database connection
+   * @return #GNUNET_OK if everything is fine
+   *         #GNUNET_NO if a transaction was rolled back
+   *         #GNUNET_SYSERR on hard errors
    */
-  void
-  (*preflight) (void *cls,
-                struct TALER_EXCHANGEDB_Session *session);
+  enum GNUNET_GenericReturnValue
+  (*preflight)(void *cls);
 
 
   /**
    * Abort/rollback a transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    */
   void
-  (*rollback) (void *cls,
-               struct TALER_EXCHANGEDB_Session *session);
+  (*rollback) (void *cls);
 
 
   /**
@@ -2179,7 +2150,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param cb_cls closure for @a cb
    * @return handle useful to cancel the listener
    */
-  struct TALER_EXCHANGEDB_EventHandler *
+  struct GNUNET_DB_EventHandler *
   (*event_listen)(void *cls,
                   struct GNUNET_TIME_Relative timeout,
                   const struct GNUNET_DB_EventHeaderP *es,
@@ -2194,21 +2165,19 @@ struct TALER_EXCHANGEDB_Plugin
    */
   void
   (*event_listen_cancel)(void *cls,
-                         struct TALER_EXCHANGEDB_EventHandler *eh);
+                         struct GNUNET_DB_EventHandler *eh);
 
 
   /**
    * Notify all that listen on @a es of an event.
    *
    * @param cls database context to use
-   * @param session connection to use
    * @param es specification of the event to generate
    * @param extra additional event data provided
    * @param extra_size number of bytes in @a extra
    */
   void
   (*event_notify)(void *cls,
-                  struct TALER_EXCHANGEDB_Session *session,
                   const struct GNUNET_DB_EventHeaderP *es,
                   const void *extra,
                   size_t extra_size);
@@ -2220,7 +2189,6 @@ struct TALER_EXCHANGEDB_Plugin
    * with this key have.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @param denom_pub the public key used for signing coins of this 
denomination
    * @param issue issuing information with value, fees and other info about 
the denomination
    * @return status of the query
@@ -2228,7 +2196,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_denomination_info)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_DenominationPublicKey *denom_pub,
     const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue);
 
@@ -2237,7 +2204,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Fetch information about a denomination key.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @param denom_pub_hash hash of the public key used for signing coins of 
this denomination
    * @param[out] issue set to issue information with value, fees and other 
info about the coin
    * @return transaction status code
@@ -2245,7 +2211,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*get_denomination_info)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *denom_pub_hash,
     struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue);
 
@@ -2257,14 +2222,12 @@ struct TALER_EXCHANGEDB_Plugin
    * be initialized yet.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session session to use
    * @param cb function to call on each denomination key
    * @param cb_cls closure for @a cb
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*iterate_denomination_info)(void *cls,
-                               struct TALER_EXCHANGEDB_Session *session,
                                TALER_EXCHANGEDB_DenominationCallback cb,
                                void *cb_cls);
 
@@ -2272,7 +2235,7 @@ struct TALER_EXCHANGEDB_Plugin
   /**
    * Function called to invoke @a cb on every known denomination key (revoked
    * and non-revoked) that has been signed by the master key. Runs in its own
-   * read-only transaction (hence no session provided).
+   * read-only transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param cb function to call on each denomination key
@@ -2287,8 +2250,7 @@ struct TALER_EXCHANGEDB_Plugin
   /**
    * Function called to invoke @a cb on every non-revoked exchange signing key
    * that has been signed by the master key.  Revoked and (for signing!)
-   * expired keys are skipped. Runs in its own read-only transaction (hence no
-   * session provided).
+   * expired keys are skipped. Runs in its own read-only transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param cb function to call on each signing key
@@ -2303,8 +2265,7 @@ struct TALER_EXCHANGEDB_Plugin
 
   /**
    * Function called to invoke @a cb on every active auditor. Disabled
-   * auditors are skipped. Runs in its own read-only transaction (hence no
-   * session provided).
+   * auditors are skipped. Runs in its own read-only transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param cb function to call on each active auditor
@@ -2320,8 +2281,7 @@ struct TALER_EXCHANGEDB_Plugin
   /**
    * Function called to invoke @a cb on every denomination with an active
    * auditor. Disabled auditors and denominations without auditor are
-   * skipped. Runs in its own read-only transaction (hence no session
-   * provided).
+   * skipped. Runs in its own read-only transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param cb function to call on each active auditor-denomination pair
@@ -2339,7 +2299,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Get the summary of a reserve.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session the database connection handle
    * @param[in,out] reserve the reserve data.  The public key of the reserve 
should be set
    *          in this structure; it is used to query the database.  The balance
    *          and expiration are then filled accordingly.
@@ -2347,7 +2306,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*reserves_get)(void *cls,
-                  struct TALER_EXCHANGEDB_Session *session,
                   struct TALER_EXCHANGEDB_Reserve *reserve);
 
 
@@ -2356,7 +2314,6 @@ struct TALER_EXCHANGEDB_Plugin
    * also created through this function.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session the database session handle
    * @param reserve_pub public key of the reserve
    * @param balance the amount that has to be added to the reserve
    * @param execution_time when was the amount added
@@ -2366,7 +2323,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*reserves_in_insert)(void *cls,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_ReservePublicKeyP *reserve_pub,
                         const struct TALER_Amount *balance,
                         struct GNUNET_TIME_Absolute execution_time,
@@ -2380,7 +2336,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Used by the wirewatch process when resuming.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session the database connection handle
    * @param exchange_account_name name of the section in the exchange's 
configuration
    *                       for the account that we are tracking here
    * @param[out] wire_reference set to unique reference identifying the wire 
transfer
@@ -2388,7 +2343,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_latest_reserve_in_reference)(void *cls,
-                                     struct TALER_EXCHANGEDB_Session *session,
                                      const char *exchange_account_name,
                                      uint64_t *wire_reference);
 
@@ -2399,7 +2353,6 @@ struct TALER_EXCHANGEDB_Plugin
    * idempotency of the request.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection to use
    * @param h_blind hash of the blinded coin to be signed (will match
    *                `h_coin_envelope` in the @a collectable to be returned)
    * @param collectable corresponding collectable coin (blind signature)
@@ -2408,7 +2361,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_withdraw_info)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct GNUNET_HashCode *h_blind,
                        struct TALER_EXCHANGEDB_CollectableBlindcoin 
*collectable);
 
@@ -2418,16 +2370,14 @@ struct TALER_EXCHANGEDB_Plugin
    * message.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection to use
    * @param collectable corresponding collectable coin (blind signature)
    *                    if a coin is found
    * @return statement execution status
    */
   enum GNUNET_DB_QueryStatus
-  (*insert_withdraw_info)(void *cls,
-                          struct TALER_EXCHANGEDB_Session *session,
-                          const struct
-                          TALER_EXCHANGEDB_CollectableBlindcoin *collectable);
+  (*insert_withdraw_info)(
+    void *cls,
+    const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable);
 
 
   /**
@@ -2435,14 +2385,12 @@ struct TALER_EXCHANGEDB_Plugin
    * reserve.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @param reserve_pub public key of the reserve
    * @param[out] rhp set to known transaction history (NULL if reserve is 
unknown)
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
   (*get_reserve_history)(void *cls,
-                         struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_ReservePublicKeyP *reserve_pub,
                          struct TALER_EXCHANGEDB_ReserveHistory **rhp);
 
@@ -2462,13 +2410,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Count the number of known coins by denomination.
    *
    * @param cls database connection plugin state
-   * @param session database session
    * @param denom_pub_hash denomination to count by
    * @return number of coins if non-negative, otherwise an `enum 
GNUNET_DB_QueryStatus`
    */
   long long
   (*count_known_coins) (void *cls,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct GNUNET_HashCode *denom_pub_hash);
 
 
@@ -2476,7 +2422,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Make sure the given @a coin is known to the database.
    *
    * @param cls database connection plugin state
-   * @param session database session
    * @param coin the coin that must be made known
    * @return database transaction status, non-negative on success
    */
@@ -2508,7 +2453,6 @@ struct TALER_EXCHANGEDB_Plugin
     TALER_EXCHANGEDB_CKS_CONFLICT = -3,
   }
   (*ensure_coin_known)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct TALER_CoinPublicInfo *coin);
 
 
@@ -2516,13 +2460,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Retrieve information about the given @a coin from the database.
    *
    * @param cls database connection plugin state
-   * @param session database session
    * @param coin the coin that must be made known
    * @return database transaction status, non-negative on success
    */
   enum GNUNET_DB_QueryStatus
   (*get_known_coin)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     const struct TALER_CoinSpendPublicKeyP *coin_pub,
                     struct TALER_CoinPublicInfo *coin_info);
 
@@ -2531,14 +2473,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Retrieve the denomination of a known coin.
    *
    * @param cls the plugin closure
-   * @param session the database session handle
    * @param coin_pub the public key of the coin to search for
    * @param[out] denom_hash where to store the hash of the coins denomination
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*get_coin_denomination)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_CoinSpendPublicKeyP *coin_pub,
                            struct GNUNET_HashCode *denom_hash);
 
@@ -2547,7 +2487,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Check if we have the specified deposit already in the database.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param deposit deposit to search for
    * @param check_extras whether to check extra fields or not
    * @param[out] deposit_fee set to the deposit fee the exchange charged
@@ -2558,7 +2497,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*have_deposit)(void *cls,
-                  struct TALER_EXCHANGEDB_Session *session,
                   const struct TALER_EXCHANGEDB_Deposit *deposit,
                   int check_extras,
                   struct TALER_Amount *deposit_fee,
@@ -2569,14 +2507,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert information about deposited coin into the database.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param exchange_timestamp time the exchange received the deposit request
    * @param deposit deposit information to store
    * @return query result status
    */
   enum GNUNET_DB_QueryStatus
   (*insert_deposit)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     struct GNUNET_TIME_Absolute exchange_timestamp,
                     const struct TALER_EXCHANGEDB_Deposit *deposit);
 
@@ -2585,13 +2521,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert information about refunded coin into the database.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param refund refund information to store
    * @return query result status
    */
   enum GNUNET_DB_QueryStatus
   (*insert_refund)(void *cls,
-                   struct TALER_EXCHANGEDB_Session *session,
                    const struct TALER_EXCHANGEDB_Refund *refund);
 
 
@@ -2599,7 +2533,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Select refunds by @a coin_pub, @a merchant_pub and @a h_contract.
    *
    * @param cls closure of plugin
-   * @param session database handle to use
    * @param coin_pub coin to get refunds for
    * @param merchant_pub merchant to get refunds for
    * @param h_contract_pub contract (hash) to get refunds for
@@ -2609,7 +2542,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_refunds_by_coin)(void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct TALER_CoinSpendPublicKeyP *coin_pub,
                             const struct TALER_MerchantPublicKeyP 
*merchant_pub,
                             const struct GNUNET_HashCode *h_contract,
@@ -2623,13 +2555,11 @@ struct TALER_EXCHANGEDB_Plugin
    * returned by @e iterate_ready_deposits()
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param deposit_rowid identifies the deposit row to modify
    * @return query result status
    */
   enum GNUNET_DB_QueryStatus
   (*mark_deposit_tiny)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        uint64_t rowid);
 
 
@@ -2638,7 +2568,6 @@ struct TALER_EXCHANGEDB_Plugin
    * cannot be refunded anymore.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param coin_pub the coin to check for deposit
    * @param merchant_pub merchant to receive the deposit
    * @param h_contract_terms contract terms of the deposit
@@ -2649,7 +2578,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*test_deposit_done)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        const struct TALER_CoinSpendPublicKeyP *coin_pub,
                        const struct TALER_MerchantPublicKeyP *merchant_pub,
                        const struct GNUNET_HashCode *h_contract_terms,
@@ -2662,13 +2590,11 @@ struct TALER_EXCHANGEDB_Plugin
    * @e iterate_ready_deposits() or @e iterate_matching_deposits().
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param deposit_rowid identifies the deposit row to modify
    * @return query result status
    */
   enum GNUNET_DB_QueryStatus
   (*mark_deposit_done)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        uint64_t rowid);
 
 
@@ -2678,14 +2604,12 @@ struct TALER_EXCHANGEDB_Plugin
    * execution time and refund deadlines must both be in the past.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param deposit_cb function to call for ONE such deposit
    * @param deposit_cb_cls closure for @a deposit_cb
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*get_ready_deposit)(void *cls,
-                       struct TALER_EXCHANGEDB_Session *session,
                        TALER_EXCHANGEDB_DepositIterator deposit_cb,
                        void *deposit_cb_cls);
 
@@ -2705,7 +2629,6 @@ struct TALER_EXCHANGEDB_Plugin
    * destination.  Those deposits must not already be "done".
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to the database
    * @param h_wire destination of the wire transfer
    * @param merchant_pub public key of the merchant
    * @param deposit_cb function to call for each deposit
@@ -2719,7 +2642,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*iterate_matching_deposits)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_wire,
     const struct TALER_MerchantPublicKeyP *merchant_pub,
     TALER_EXCHANGEDB_MatchingDepositIterator deposit_cb,
@@ -2731,13 +2653,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Store new melt commitment data.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database handle to use
    * @param refresh_session operational data to store
    * @return query status for the transaction
    */
   enum GNUNET_DB_QueryStatus
   (*insert_melt)(void *cls,
-                 struct TALER_EXCHANGEDB_Session *session,
                  const struct TALER_EXCHANGEDB_Refresh *refresh_session);
 
 
@@ -2745,7 +2665,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Lookup melt commitment data under the given @a rc.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database handle to use
    * @param rc commitment to use for the lookup
    * @param[out] melt where to store the result; note that
    *             melt->session.coin.denom_sig will be set to NULL
@@ -2754,7 +2673,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_melt)(void *cls,
-              struct TALER_EXCHANGEDB_Session *session,
               const struct TALER_RefreshCommitmentP *rc,
               struct TALER_EXCHANGEDB_Melt *melt);
 
@@ -2764,7 +2682,6 @@ struct TALER_EXCHANGEDB_Plugin
    * @a rc.
    *
    * @param cls the `struct PostgresClosure` with the plugin-specific state
-   * @param session database handle to use
    * @param rc commitment hash to use to locate the operation
    * @param[out] noreveal_index returns the "gamma" value selected by the
    *             exchange which is the index of the transfer key that is
@@ -2773,7 +2690,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_melt_index)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     const struct TALER_RefreshCommitmentP *rc,
                     uint32_t *noreveal_index);
 
@@ -2784,7 +2700,6 @@ struct TALER_EXCHANGEDB_Plugin
    * we learned or created in the reveal step.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param rc identify commitment and thus refresh operation
    * @param num_rrcs number of coins to generate, size of the @a rrcs array
    * @param rrcs information about the new coins
@@ -2796,7 +2711,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_refresh_reveal)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_RefreshCommitmentP *rc,
     uint32_t num_rrcs,
     const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs,
@@ -2810,7 +2724,6 @@ struct TALER_EXCHANGEDB_Plugin
    * created in the given refresh operation.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param rc identify commitment and thus refresh operation
    * @param cb function to call with the results
    * @param cb_cls closure for @a cb
@@ -2818,7 +2731,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_refresh_reveal)(void *cls,
-                        struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_RefreshCommitmentP *rc,
                         TALER_EXCHANGEDB_RefreshCallback cb,
                         void *cb_cls);
@@ -2831,7 +2743,6 @@ struct TALER_EXCHANGEDB_Plugin
    * the private keys of the new coins after the melt.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param coin_pub public key of the coin
    * @param ldc function to call for each session the coin was melted into
    * @param ldc_cls closure for @a tdc
@@ -2839,7 +2750,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_link_data)(void *cls,
-                   struct TALER_EXCHANGEDB_Session *session,
                    const struct TALER_CoinSpendPublicKeyP *coin_pub,
                    TALER_EXCHANGEDB_LinkCallback ldc,
                    void *tdc_cls);
@@ -2850,7 +2760,6 @@ struct TALER_EXCHANGEDB_Plugin
    * with the given coin (melt, refund, recoup and deposit operations).
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param coin_pub coin to investigate
    * @param include_recoup include recoup transactions of the coin?
    * @param[out] tlp set to list of transactions, NULL if coin is fresh
@@ -2858,7 +2767,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_coin_transactions)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_CoinSpendPublicKeyP *coin_pub,
                            int include_recoup,
                            struct TALER_EXCHANGEDB_TransactionList **tlp);
@@ -2880,7 +2788,6 @@ struct TALER_EXCHANGEDB_Plugin
    * into a wire transfer by the respective @a raw_wtid.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session database connection
    * @param wtid the raw wire transfer identifier we used
    * @param cb function to call on each transaction found
    * @param cb_cls closure for @a cb
@@ -2888,7 +2795,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_wire_transfer)(void *cls,
-                          struct TALER_EXCHANGEDB_Session *session,
                           const struct TALER_WireTransferIdentifierRawP *wtid,
                           TALER_EXCHANGEDB_AggregationDataCallback cb,
                           void *cb_cls);
@@ -2900,7 +2806,6 @@ struct TALER_EXCHANGEDB_Plugin
    * to be executed.
    *
    * @param cls closure
-   * @param session database connection
    * @param h_contract_terms hash of the proposal data
    * @param h_wire hash of merchant wire details
    * @param coin_pub public key of deposited coin
@@ -2912,7 +2817,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_transfer_by_deposit)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_contract_terms,
     const struct GNUNET_HashCode *h_wire,
     const struct TALER_CoinSpendPublicKeyP *coin_pub,
@@ -2925,7 +2829,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Function called to insert aggregation information into the DB.
    *
    * @param cls closure
-   * @param session database connection
    * @param wtid the raw wire transfer identifier we used
    * @param deposit_serial_id row in the deposits table for which this is 
aggregation data
    * @return transaction status code
@@ -2933,7 +2836,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_aggregation_tracking)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_WireTransferIdentifierRawP *wtid,
     unsigned long long deposit_serial_id);
 
@@ -2942,7 +2844,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert wire transfer fee into database.
    *
    * @param cls closure
-   * @param session database connection
    * @param wire_method which wire method is the fee about?
    * @param start_date when does the fee go into effect
    * @param end_date when does the fee end being valid
@@ -2953,7 +2854,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*insert_wire_fee)(void *cls,
-                     struct TALER_EXCHANGEDB_Session *session,
                      const char *wire_method,
                      struct GNUNET_TIME_Absolute start_date,
                      struct GNUNET_TIME_Absolute end_date,
@@ -2966,7 +2866,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Obtain wire fee from database.
    *
    * @param cls closure
-   * @param session database connection
    * @param type type of wire transfer the fee applies for
    * @param date for which date do we want the fee?
    * @param[out] start_date when does the fee go into effect
@@ -2978,7 +2877,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_wire_fee)(void *cls,
-                  struct TALER_EXCHANGEDB_Session *session,
                   const char *type,
                   struct GNUNET_TIME_Absolute date,
                   struct GNUNET_TIME_Absolute *start_date,
@@ -2993,7 +2891,6 @@ struct TALER_EXCHANGEDB_Plugin
    * remaining balances.
    *
    * @param cls closure of the plugin
-   * @param session database connection
    * @param now timestamp based on which we decide expiration
    * @param rec function to call on expired reserves
    * @param rec_cls closure for @a rec
@@ -3001,7 +2898,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_expired_reserves)(void *cls,
-                          struct TALER_EXCHANGEDB_Session *session,
                           struct GNUNET_TIME_Absolute now,
                           TALER_EXCHANGEDB_ReserveExpiredCallback rec,
                           void *rec_cls);
@@ -3011,7 +2907,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert reserve close operation into database.
    *
    * @param cls closure
-   * @param session database connection
    * @param reserve_pub which reserve is this about?
    * @param execution_date when did we perform the transfer?
    * @param receiver_account to which account do we transfer, in 
payto://-format
@@ -3022,7 +2917,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*insert_reserve_closed)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_ReservePublicKeyP *reserve_pub,
                            struct GNUNET_TIME_Absolute execution_date,
                            const char *receiver_account,
@@ -3035,7 +2929,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Function called to insert wire transfer commit data into the DB.
    *
    * @param cls closure
-   * @param session database connection
    * @param type type of the wire transfer (i.e. "iban")
    * @param buf buffer with wire transfer preparation data
    * @param buf_size number of bytes in @a buf
@@ -3043,7 +2936,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*wire_prepare_data_insert)(void *cls,
-                              struct TALER_EXCHANGEDB_Session *session,
                               const char *type,
                               const char *buf,
                               size_t buf_size);
@@ -3053,13 +2945,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Function called to mark wire transfer commit data as finished.
    *
    * @param cls closure
-   * @param session database connection
    * @param rowid which entry to mark as finished
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*wire_prepare_data_mark_finished)(void *cls,
-                                     struct TALER_EXCHANGEDB_Session *session,
                                      uint64_t rowid);
 
 
@@ -3067,13 +2957,11 @@ struct TALER_EXCHANGEDB_Plugin
    * Function called to mark wire transfer as failed.
    *
    * @param cls closure
-   * @param session database connection
    * @param rowid which entry to mark as failed
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*wire_prepare_data_mark_failed)(void *cls,
-                                   struct TALER_EXCHANGEDB_Session *session,
                                    uint64_t rowid);
 
 
@@ -3082,14 +2970,12 @@ struct TALER_EXCHANGEDB_Plugin
    * preparation data. Fetches at most one item.
    *
    * @param cls closure
-   * @param session database connection
    * @param cb function to call for ONE unfinished item
    * @param cb_cls closure for @a cb
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*wire_prepare_data_get)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            TALER_EXCHANGEDB_WirePreparationIterator cb,
                            void *cb_cls);
 
@@ -3100,19 +2986,16 @@ struct TALER_EXCHANGEDB_Plugin
    * and only add the wire transfer out at the end.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session connection to use
    * @return #GNUNET_OK on success
    */
   int
-  (*start_deferred_wire_out) (void *cls,
-                              struct TALER_EXCHANGEDB_Session *session);
+  (*start_deferred_wire_out) (void *cls);
 
 
   /**
    * Store information about an outgoing wire transfer that was executed.
    *
    * @param cls closure
-   * @param session database connection
    * @param date time of the wire transfer
    * @param wtid subject of the wire transfer
    * @param wire_account details about the receiver account of the wire 
transfer,
@@ -3125,7 +3008,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*store_wire_transfer_out)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     struct GNUNET_TIME_Absolute date,
     const struct TALER_WireTransferIdentifierRawP *wtid,
     const json_t *wire_account,
@@ -3150,7 +3032,6 @@ struct TALER_EXCHANGEDB_Plugin
    * order.
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
    * @param cb_cls closure for @a cb
@@ -3158,7 +3039,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_deposits_above_serial_id)(void *cls,
-                                     struct TALER_EXCHANGEDB_Session *session,
                                      uint64_t serial_id,
                                      TALER_EXCHANGEDB_DepositCallback cb,
                                      void *cb_cls);
@@ -3168,7 +3048,6 @@ struct TALER_EXCHANGEDB_Plugin
    * order.
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
    * @param cb_cls closure for @a cb
@@ -3176,7 +3055,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_refreshes_above_serial_id)(void *cls,
-                                      struct TALER_EXCHANGEDB_Session *session,
                                       uint64_t serial_id,
                                       TALER_EXCHANGEDB_RefreshesCallback cb,
                                       void *cb_cls);
@@ -3187,7 +3065,6 @@ struct TALER_EXCHANGEDB_Plugin
    * order.
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
    * @param cb_cls closure for @a cb
@@ -3195,7 +3072,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_refunds_above_serial_id)(void *cls,
-                                    struct TALER_EXCHANGEDB_Session *session,
                                     uint64_t serial_id,
                                     TALER_EXCHANGEDB_RefundCallback cb,
                                     void *cb_cls);
@@ -3206,7 +3082,6 @@ struct TALER_EXCHANGEDB_Plugin
    * in monotonically increasing order.
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
    * @param cb_cls closure for @a cb
@@ -3214,7 +3089,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_reserves_in_above_serial_id)(void *cls,
-                                        struct TALER_EXCHANGEDB_Session 
*session,
                                         uint64_t serial_id,
                                         TALER_EXCHANGEDB_ReserveInCallback cb,
                                         void *cb_cls);
@@ -3225,7 +3099,6 @@ struct TALER_EXCHANGEDB_Plugin
    * in monotonically increasing order by @a account_name.
    *
    * @param cls closure
-   * @param session database connection
    * @param account_name name of the account for which we do the selection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
@@ -3235,7 +3108,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_reserves_in_above_serial_id_by_account)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const char *account_name,
     uint64_t serial_id,
     TALER_EXCHANGEDB_ReserveInCallback cb,
@@ -3247,7 +3119,6 @@ struct TALER_EXCHANGEDB_Plugin
    * in monotonically increasing order.
    *
    * @param cls closure
-   * @param session database connection
    * @param account_name name of the account for which we do the selection
    * @param serial_id highest serial ID to exclude (select strictly larger)
    * @param cb function to call on each result
@@ -3257,7 +3128,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_withdrawals_above_serial_id)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     uint64_t serial_id,
     TALER_EXCHANGEDB_WithdrawCallback cb,
     void *cb_cls);
@@ -3268,7 +3138,6 @@ struct TALER_EXCHANGEDB_Plugin
    * executed, ordered by serial ID (monotonically increasing).
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id lowest serial ID to include (select larger or equal)
    * @param cb function to call for ONE unfinished item
    * @param cb_cls closure for @a cb
@@ -3276,7 +3145,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_wire_out_above_serial_id)(void *cls,
-                                     struct TALER_EXCHANGEDB_Session *session,
                                      uint64_t serial_id,
                                      TALER_EXCHANGEDB_WireTransferOutCallback 
cb,
                                      void *cb_cls);
@@ -3286,7 +3154,6 @@ struct TALER_EXCHANGEDB_Plugin
    * executed, ordered by serial ID (monotonically increasing).
    *
    * @param cls closure
-   * @param session database connection
    * @param account_name name to select by
    * @param serial_id lowest serial ID to include (select larger or equal)
    * @param cb function to call for ONE unfinished item
@@ -3296,7 +3163,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_wire_out_above_serial_id_by_account)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const char *account_name,
     uint64_t serial_id,
     TALER_EXCHANGEDB_WireTransferOutCallback cb,
@@ -3308,7 +3174,6 @@ struct TALER_EXCHANGEDB_Plugin
    * received, ordered by serial ID (monotonically increasing).
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id lowest serial ID to include (select larger or equal)
    * @param cb function to call for ONE unfinished item
    * @param cb_cls closure for @a cb
@@ -3316,7 +3181,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_recoup_above_serial_id)(void *cls,
-                                   struct TALER_EXCHANGEDB_Session *session,
                                    uint64_t serial_id,
                                    TALER_EXCHANGEDB_RecoupCallback cb,
                                    void *cb_cls);
@@ -3327,7 +3191,6 @@ struct TALER_EXCHANGEDB_Plugin
    * refreshed coins, ordered by serial ID (monotonically increasing).
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id lowest serial ID to include (select larger or equal)
    * @param cb function to call for ONE unfinished item
    * @param cb_cls closure for @a cb
@@ -3336,7 +3199,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_recoup_refresh_above_serial_id)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     uint64_t serial_id,
     TALER_EXCHANGEDB_RecoupRefreshCallback cb,
     void *cb_cls);
@@ -3347,7 +3209,6 @@ struct TALER_EXCHANGEDB_Plugin
    * triggered, ordered by serial ID (monotonically increasing).
    *
    * @param cls closure
-   * @param session database connection
    * @param serial_id lowest serial ID to include (select larger or equal)
    * @param cb function to call
    * @param cb_cls closure for @a cb
@@ -3356,7 +3217,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_reserve_closed_above_serial_id)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     uint64_t serial_id,
     TALER_EXCHANGEDB_ReserveClosedCallback cb,
     void *cb_cls);
@@ -3367,7 +3227,6 @@ struct TALER_EXCHANGEDB_Plugin
    * coin.  The funds are to be added back to the reserve.
    *
    * @param cls closure
-   * @param session database connection
    * @param reserve_pub public key of the reserve that is being refunded
    * @param coin public information about a coin
    * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_RECOUP
@@ -3381,7 +3240,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_recoup_request)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_ReservePublicKeyP *reserve_pub,
     const struct TALER_CoinPublicInfo *coin,
     const struct TALER_CoinSpendSignatureP *coin_sig,
@@ -3396,7 +3254,6 @@ struct TALER_EXCHANGEDB_Plugin
    * refreshed coin.  The funds are to be added back to the original coin.
    *
    * @param cls closure
-   * @param session database connection
    * @param coin public information about the refreshed coin
    * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_RECOUP
    * @param coin_blind blinding key of the coin
@@ -3409,7 +3266,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_recoup_refresh_request)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_CoinPublicInfo *coin,
     const struct TALER_CoinSpendSignatureP *coin_sig,
     const struct TALER_DenominationBlindingKeyP *coin_blind,
@@ -3423,14 +3279,12 @@ struct TALER_EXCHANGEDB_Plugin
    * from given the hash of the blinded coin.
    *
    * @param cls closure
-   * @param session a session
    * @param h_blind_ev hash of the blinded coin
    * @param[out] reserve_pub set to information about the reserve (on success 
only)
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*get_reserve_by_h_blind)(void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             const struct GNUNET_HashCode *h_blind_ev,
                             struct TALER_ReservePublicKeyP *reserve_pub);
 
@@ -3440,14 +3294,12 @@ struct TALER_EXCHANGEDB_Plugin
    * given the hash of the blinded (fresh) coin.
    *
    * @param cls closure
-   * @param session a session
    * @param h_blind_ev hash of the blinded coin
    * @param[out] old_coin_pub set to information about the old coin (on 
success only)
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*get_old_coin_by_h_blind)(void *cls,
-                             struct TALER_EXCHANGEDB_Session *session,
                              const struct GNUNET_HashCode *h_blind_ev,
                              struct TALER_CoinSpendPublicKeyP *old_coin_pub);
 
@@ -3457,7 +3309,6 @@ struct TALER_EXCHANGEDB_Plugin
    * in the database.
    *
    * @param cls closure
-   * @param session a session
    * @param denom_pub_hash hash of the revoked denomination key
    * @param master_sig signature affirming the revocation
    * @return transaction status code
@@ -3465,7 +3316,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_denomination_revocation)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *denom_pub_hash,
     const struct TALER_MasterSignatureP *master_sig);
 
@@ -3475,7 +3325,6 @@ struct TALER_EXCHANGEDB_Plugin
    * the database.
    *
    * @param cls closure
-   * @param session a session
    * @param denom_pub_hash hash of the revoked denomination key
    * @param[out] master_sig signature affirming the revocation
    * @param[out] rowid row where the information is stored
@@ -3483,7 +3332,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*get_denomination_revocation)(void *cls,
-                                 struct TALER_EXCHANGEDB_Session *session,
                                  const struct GNUNET_HashCode *denom_pub_hash,
                                  struct TALER_MasterSignatureP *master_sig,
                                  uint64_t *rowid);
@@ -3495,7 +3343,6 @@ struct TALER_EXCHANGEDB_Plugin
    * been deposited between @a start_date and @a end_date.
    *
    * @param cls closure
-   * @param session a session
    * @param start_date lower bound on the requested wire execution date
    * @param end_date upper bound on the requested wire execution date
    * @param cb function to call on all such deposits
@@ -3504,7 +3351,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_deposits_missing_wire)(void *cls,
-                                  struct TALER_EXCHANGEDB_Session *session,
                                   struct GNUNET_TIME_Absolute start_date,
                                   struct GNUNET_TIME_Absolute end_date,
                                   TALER_EXCHANGEDB_WireMissingCallback cb,
@@ -3515,14 +3361,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Check the last date an auditor was modified.
    *
    * @param cls closure
-   * @param session a session
    * @param auditor_pub key to look up information for
    * @param[out] last_date last modification date to auditor status
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_auditor_timestamp)(void *cls,
-                              struct TALER_EXCHANGEDB_Session *session,
                               const struct TALER_AuditorPublicKeyP 
*auditor_pub,
                               struct GNUNET_TIME_Absolute *last_date);
 
@@ -3531,7 +3375,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Lookup current state of an auditor.
    *
    * @param cls closure
-   * @param session a session
    * @param auditor_pub key to look up information for
    * @param[out] auditor_url set to the base URL of the auditor's REST API; 
memory to be
    *            released by the caller!
@@ -3540,7 +3383,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_auditor_status)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const struct TALER_AuditorPublicKeyP *auditor_pub,
                            char **auditor_url,
                            bool *enabled);
@@ -3550,7 +3392,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert information about an auditor that will audit this exchange.
    *
    * @param cls closure
-   * @param session a session
    * @param auditor_pub key of the auditor
    * @param auditor_url base URL of the auditor's REST service
    * @param auditor_name name of the auditor (for humans)
@@ -3560,7 +3401,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*insert_auditor)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     const struct TALER_AuditorPublicKeyP *auditor_pub,
                     const char *auditor_url,
                     const char *auditor_name,
@@ -3571,7 +3411,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Update information about an auditor that will audit this exchange.
    *
    * @param cls closure
-   * @param session a session
    * @param auditor_pub key of the auditor (primary key for the existing 
record)
    * @param auditor_url base URL of the auditor's REST service, to be updated
    * @param auditor_name name of the auditor (for humans)
@@ -3582,7 +3421,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*update_auditor)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     const struct TALER_AuditorPublicKeyP *auditor_pub,
                     const char *auditor_url,
                     const char *auditor_name,
@@ -3594,14 +3432,12 @@ struct TALER_EXCHANGEDB_Plugin
    * Check the last date an exchange wire account was modified.
    *
    * @param cls closure
-   * @param session a session
    * @param payto_uri key to look up information for
    * @param[out] last_date last modification date to auditor status
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_wire_timestamp)(void *cls,
-                           struct TALER_EXCHANGEDB_Session *session,
                            const char *payto_uri,
                            struct GNUNET_TIME_Absolute *last_date);
 
@@ -3610,7 +3446,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert information about an wire account used by this exchange.
    *
    * @param cls closure
-   * @param session a session
    * @param payto_uri wire account of the exchange
    * @param start_date date when the account was added by the offline system
    *                      (only to be used for replay detection)
@@ -3620,7 +3455,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*insert_wire)(void *cls,
-                 struct TALER_EXCHANGEDB_Session *session,
                  const char *payto_uri,
                  struct GNUNET_TIME_Absolute start_date,
                  const struct TALER_MasterSignatureP *master_sig);
@@ -3630,7 +3464,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Update information about a wire account of the exchange.
    *
    * @param cls closure
-   * @param session a session
    * @param payto_uri account the update is about
    * @param change_date date when the account status was last changed
    *                      (only to be used for replay detection)
@@ -3639,7 +3472,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*update_wire)(void *cls,
-                 struct TALER_EXCHANGEDB_Session *session,
                  const char *payto_uri,
                  struct GNUNET_TIME_Absolute change_date,
                  bool enabled);
@@ -3680,7 +3512,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Store information about a revoked online signing key.
    *
    * @param cls closure
-   * @param session a session (can be NULL)
    * @param exchange_pub exchange online signing key that was revoked
    * @param master_sig signature affirming the revocation
    * @return transaction status code
@@ -3688,7 +3519,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_signkey_revocation)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_ExchangePublicKeyP *exchange_pub,
     const struct TALER_MasterSignatureP *master_sig);
 
@@ -3697,7 +3527,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Obtain information about a revoked online signing key.
    *
    * @param cls closure
-   * @param session a session (can be NULL)
    * @param exchange_pub exchange online signing key that was revoked
    * @param[out] master_sig signature affirming the revocation
    * @return transaction status code
@@ -3705,7 +3534,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_signkey_revocation)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_ExchangePublicKeyP *exchange_pub,
     struct TALER_MasterSignatureP *master_sig);
 
@@ -3714,7 +3542,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Lookup information about current denomination key.
    *
    * @param cls closure
-   * @param session a session
    * @param h_denom_pub hash of the denomination public key
    * @param[out] meta set to various meta data about the key
    * @return transaction status code
@@ -3722,7 +3549,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_denomination_key)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_denom_pub,
     struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta);
 
@@ -3731,7 +3557,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Add denomination key.
    *
    * @param cls closure
-   * @param session a session
    * @param h_denom_pub hash of the denomination public key
    * @param denom_pub the denomination public key
    * @param meta meta data about the denomination
@@ -3741,7 +3566,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*add_denomination_key)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_denom_pub,
     const struct TALER_DenominationPublicKey *denom_pub,
     const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
@@ -3753,7 +3577,6 @@ struct TALER_EXCHANGEDB_Plugin
    * denomination key by adding the master signature.
    *
    * @param cls closure
-   * @param session a session
    * @param exchange_pub the exchange online signing public key
    * @param meta meta data about @a exchange_pub
    * @param master_sig master signature to add
@@ -3762,7 +3585,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*activate_signing_key)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_ExchangePublicKeyP *exchange_pub,
     const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
     const struct TALER_MasterSignatureP *master_sig);
@@ -3772,7 +3594,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Lookup signing key meta data.
    *
    * @param cls closure
-   * @param session a session
    * @param exchange_pub the exchange online signing public key
    * @param[out] meta meta data about @a exchange_pub
    * @return transaction status code
@@ -3780,7 +3601,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_signing_key)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct TALER_ExchangePublicKeyP *exchange_pub,
     struct TALER_EXCHANGEDB_SignkeyMetaData *meta);
 
@@ -3789,7 +3609,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Insert information about an auditor auditing a denomination key.
    *
    * @param cls closure
-   * @param session a session
    * @param h_denom_pub the audited denomination
    * @param auditor_pub the auditor's key
    * @param auditor_sig signature affirming the auditor's audit activity
@@ -3798,7 +3617,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_auditor_denom_sig)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_denom_pub,
     const struct TALER_AuditorPublicKeyP *auditor_pub,
     const struct TALER_AuditorSignatureP *auditor_sig);
@@ -3808,7 +3626,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Obtain information about an auditor auditing a denomination key.
    *
    * @param cls closure
-   * @param session a session
    * @param h_denom_pub the audited denomination
    * @param auditor_pub the auditor's key
    * @param[out] auditor_sig set to signature affirming the auditor's audit 
activity
@@ -3817,7 +3634,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*select_auditor_denom_sig)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const struct GNUNET_HashCode *h_denom_pub,
     const struct TALER_AuditorPublicKeyP *auditor_pub,
     struct TALER_AuditorSignatureP *auditor_sig);
@@ -3827,7 +3643,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Lookup information about known wire fees.
    *
    * @param cls closure
-   * @param session a session
    * @param wire_method the wire method to lookup fees for
    * @param start_time starting time of fee
    * @param end_time end time of fee
@@ -3842,7 +3657,6 @@ struct TALER_EXCHANGEDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_wire_fee_by_time)(
     void *cls,
-    struct TALER_EXCHANGEDB_Session *session,
     const char *wire_method,
     struct GNUNET_TIME_Absolute start_time,
     struct GNUNET_TIME_Absolute end_time,
@@ -3855,7 +3669,6 @@ struct TALER_EXCHANGEDB_Plugin
    * exchange-auditor database replication.
    *
    * @param cls closure
-   * @param session a session
    * @param table table for which we should return the serial
    * @param[out] latest serial number in use
    * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
@@ -3863,7 +3676,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_serial_by_table)(void *cls,
-                            struct TALER_EXCHANGEDB_Session *session,
                             enum TALER_EXCHANGEDB_ReplicatedTable table,
                             uint64_t *serial);
 
@@ -3872,7 +3684,6 @@ struct TALER_EXCHANGEDB_Plugin
    * exchange-auditor database replication.
    *
    * @param cls closure
-   * @param session a session
    * @param table table for which we should return the serial
    * @param serial largest serial number to exclude
    * @param cb function to call on the records
@@ -3882,7 +3693,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*lookup_records_by_table)(void *cls,
-                             struct TALER_EXCHANGEDB_Session *session,
                              enum TALER_EXCHANGEDB_ReplicatedTable table,
                              uint64_t serial,
                              TALER_EXCHANGEDB_ReplicationCallback cb,
@@ -3894,20 +3704,18 @@ struct TALER_EXCHANGEDB_Plugin
    * replication.
    *
    * @param cls closure
-   * @param session a session
    * @param tb table data to insert
    * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
    *         @a table does not have a serial number
    */
   enum GNUNET_DB_QueryStatus
   (*insert_records_by_table)(void *cls,
-                             struct TALER_EXCHANGEDB_Session *session,
                              const struct TALER_EXCHANGEDB_TableData *td);
 
 
   /**
    * Function called to grab a work shard on an operation @a op. Runs in its
-   * own transaction (hence no session provided).
+   * own transaction.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param job_name name of the operation to grab a word shard for
@@ -3930,7 +3738,6 @@ struct TALER_EXCHANGEDB_Plugin
    * Function called to persist that work on a shard was completed.
    *
    * @param cls the @e cls of this struct with the plugin-specific state
-   * @param session a session
    * @param job_name name of the operation to grab a word shard for
    * @param start_row inclusive start row of the shard
    * @param end_row exclusive end row of the shard
@@ -3938,7 +3745,6 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*complete_shard)(void *cls,
-                    struct TALER_EXCHANGEDB_Session *session,
                     const char *job_name,
                     uint64_t start_row,
                     uint64_t end_row);
diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h
index 0e30d660..3af413fa 100644
--- a/src/include/taler_mhd_lib.h
+++ b/src/include/taler_mhd_lib.h
@@ -467,6 +467,35 @@ TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
                 uint16_t *port);
 
 
+/**
+ * Start to run an event loop for @a daemon.
+ * Only one daemon can be running per process
+ * using this API.
+ *
+ * @param daemon the MHD service to run
+ */
+void
+TALER_MHD_daemon_start (struct MHD_Daemon *daemon);
+
+
+/**
+ * Stop running the event loop for MHD.
+ *
+ * @return the daemon that we were previously running,
+ *       or NULL if none was active
+ */
+struct MHD_Daemon *
+TALER_MHD_daemon_stop (void);
+
+
+/**
+ * Trigger MHD daemon that is running. Needed when
+ * a connection was resumed.
+ */
+void
+TALER_MHD_daemon_trigger (void);
+
+
 /**
  * Prepared responses for legal documents
  * (terms of service, privacy policy).
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index af391693..7768a7f6 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -105,10 +105,6 @@ struct TALER_TESTING_DatabaseConnection
    */
   struct TALER_EXCHANGEDB_Plugin *plugin;
 
-  /**
-   * Session with the database.
-   */
-  struct TALER_EXCHANGEDB_Session *session;
 };
 
 struct TALER_TESTING_LibeufinServices
diff --git a/src/lib/exchange_api_reserves_get.c 
b/src/lib/exchange_api_reserves_get.c
index 563deeaf..7f919ef8 100644
--- a/src/lib/exchange_api_reserves_get.c
+++ b/src/lib/exchange_api_reserves_get.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2020 Taler Systems SA
+  Copyright (C) 2014-2021 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -234,33 +234,18 @@ handle_reserves_get_finished (void *cls,
 }
 
 
-/**
- * Submit a request to obtain the transaction history of a reserve
- * from the exchange.  Note that while we return the full response to the
- * caller for further processing, we do already verify that the
- * response is well-formed (i.e. that signatures included in the
- * response are all valid and add up to the balance).  If the exchange's
- * reply is not well-formed, we return an HTTP status code of zero to
- * @a cb.
- *
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param reserve_pub public key of the reserve to inspect
- * @param cb the callback to call when a reply for this request is available
- * @param cb_cls closure for the above callback
- * @return a handle for this request; NULL if the inputs are invalid (i.e.
- *         signatures fail to verify).  In this case, the callback is not 
called.
- */
 struct TALER_EXCHANGE_ReservesGetHandle *
-TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange,
-                             const struct
-                             TALER_ReservePublicKeyP *reserve_pub,
-                             TALER_EXCHANGE_ReservesGetCallback cb,
-                             void *cb_cls)
+TALER_EXCHANGE_reserves_get (
+  struct TALER_EXCHANGE_Handle *exchange,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct GNUNET_TIME_Relative timeout,
+  TALER_EXCHANGE_ReservesGetCallback cb,
+  void *cb_cls)
 {
   struct TALER_EXCHANGE_ReservesGetHandle *rgh;
   struct GNUNET_CURL_Context *ctx;
   CURL *eh;
-  char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 16];
+  char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 16 + 32];
 
   if (GNUNET_YES !=
       TEAH_handle_is_ready (exchange))
@@ -271,17 +256,31 @@ TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle 
*exchange,
   {
     char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
     char *end;
+    char timeout_str[32];
 
-    end = GNUNET_STRINGS_data_to_string (reserve_pub,
-                                         sizeof (struct
-                                                 TALER_ReservePublicKeyP),
-                                         pub_str,
-                                         sizeof (pub_str));
+    end = GNUNET_STRINGS_data_to_string (
+      reserve_pub,
+      sizeof (struct TALER_ReservePublicKeyP),
+      pub_str,
+      sizeof (pub_str));
     *end = '\0';
-    GNUNET_snprintf (arg_str,
-                     sizeof (arg_str),
-                     "/reserves/%s",
-                     pub_str);
+    GNUNET_snprintf (timeout_str,
+                     sizeof (timeout_str),
+                     "%llu",
+                     (unsigned long long)
+                     (timeout.rel_value_us
+                      / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us));
+    if (GNUNET_TIME_relative_is_zero (timeout))
+      GNUNET_snprintf (arg_str,
+                       sizeof (arg_str),
+                       "/reserves/%s",
+                       pub_str);
+    else
+      GNUNET_snprintf (arg_str,
+                       sizeof (arg_str),
+                       "/reserves/%s?timeout_ms=%s",
+                       pub_str,
+                       timeout_str);
   }
   rgh = GNUNET_new (struct TALER_EXCHANGE_ReservesGetHandle);
   rgh->exchange = exchange;
@@ -312,15 +311,9 @@ TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle 
*exchange,
 }
 
 
-/**
- * Cancel a reserve status request.  This function cannot be used
- * on a request handle if a response is already served for it.
- *
- * @param rgh the reserve status request handle
- */
 void
-TALER_EXCHANGE_reserves_get_cancel (struct
-                                    TALER_EXCHANGE_ReservesGetHandle *rgh)
+TALER_EXCHANGE_reserves_get_cancel (
+  struct TALER_EXCHANGE_ReservesGetHandle *rgh)
 {
   if (NULL != rgh->job)
   {
@@ -332,4 +325,4 @@ TALER_EXCHANGE_reserves_get_cancel (struct
 }
 
 
-/* end of exchange_api_reserve.c */
+/* end of exchange_api_reserves_get.c */
diff --git a/src/mhd/Makefile.am b/src/mhd/Makefile.am
index 059c275c..f7f052d5 100644
--- a/src/mhd/Makefile.am
+++ b/src/mhd/Makefile.am
@@ -13,7 +13,8 @@ libtalermhd_la_SOURCES = \
   mhd_config.c \
   mhd_legal.c \
   mhd_parsing.c \
-  mhd_responses.c
+  mhd_responses.c \
+  mhd_run.c
 libtalermhd_la_LDFLAGS = \
   -version-info 0:0:0 \
   -no-undefined
diff --git a/src/mhd/mhd_config.c b/src/mhd/mhd_config.c
index a619bba1..d6e1a25c 100644
--- a/src/mhd/mhd_config.c
+++ b/src/mhd/mhd_config.c
@@ -322,6 +322,53 @@ TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
   char *bind_to;
   struct GNUNET_NETWORK_Handle *nh;
 
+  /* try systemd passing first */
+  {
+    const char *listen_pid;
+    const char *listen_fds;
+
+    /* check for systemd-style FD passing */
+    listen_pid = getenv ("LISTEN_PID");
+    listen_fds = getenv ("LISTEN_FDS");
+    if ( (NULL != listen_pid) &&
+         (NULL != listen_fds) &&
+         (getpid () == strtol (listen_pid,
+                               NULL,
+                               10)) &&
+         (1 == strtoul (listen_fds,
+                        NULL,
+                        10)) )
+    {
+      int fh;
+      int flags;
+
+      fh = 3;
+      flags = fcntl (fh,
+                     F_GETFD);
+      if ( (-1 == flags) &&
+           (EBADF == errno) )
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Bad listen socket passed, ignored\n");
+        fh = -1;
+      }
+      flags |= FD_CLOEXEC;
+      if ( (-1 != fh) &&
+           (0 != fcntl (fh,
+                        F_SETFD,
+                        flags)) )
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                             "fcntl");
+      if (-1 != fh)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "Successfully obtained listen socket from hypervisor\n");
+        return fh;
+      }
+    }
+  }
+
+  /* now try configuration file */
   *port = 0;
   {
     char *serve_unixpath;
diff --git a/src/mhd/mhd_run.c b/src/mhd/mhd_run.c
new file mode 100644
index 00000000..8a3c369b
--- /dev/null
+++ b/src/mhd/mhd_run.c
@@ -0,0 +1,174 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2019-2021 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file mhd_run.c
+ * @brief API for running an MHD daemon with the
+ *        GNUnet scheduler
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_json_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include "taler_util.h"
+#include "taler_mhd_lib.h"
+
+
+/**
+ * Set if we should immediately #MHD_run again.
+ */
+static int triggered;
+
+/**
+ * Task running the HTTP server.
+ */
+static struct GNUNET_SCHEDULER_Task *mhd_task;
+
+/**
+ * The MHD daemon we are running.
+ */
+static struct MHD_Daemon *mhd;
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static struct GNUNET_SCHEDULER_Task *
+prepare_daemon (void);
+
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ *
+ * @param cls NULL
+ */
+static void
+run_daemon (void *cls)
+{
+  mhd_task = NULL;
+  do {
+    triggered = 0;
+    GNUNET_assert (MHD_YES ==
+                   MHD_run (mhd));
+  } while (0 != triggered);
+  mhd_task = prepare_daemon ();
+}
+
+
+/**
+ * Function that queries MHD's select sets and starts the task waiting for
+ * them.
+ *
+ * @return task handle for the MHD task.
+ */
+static struct GNUNET_SCHEDULER_Task *
+prepare_daemon (void)
+{
+  struct GNUNET_SCHEDULER_Task *ret;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  struct GNUNET_NETWORK_FDSet *wrs;
+  struct GNUNET_NETWORK_FDSet *wws;
+  int max;
+  MHD_UNSIGNED_LONG_LONG timeout;
+  int haveto;
+  struct GNUNET_TIME_Relative tv;
+
+  FD_ZERO (&rs);
+  FD_ZERO (&ws);
+  FD_ZERO (&es);
+  wrs = GNUNET_NETWORK_fdset_create ();
+  wws = GNUNET_NETWORK_fdset_create ();
+  max = -1;
+  GNUNET_assert (MHD_YES ==
+                 MHD_get_fdset (mhd,
+                                &rs,
+                                &ws,
+                                &es,
+                                &max));
+  haveto = MHD_get_timeout (mhd,
+                            &timeout);
+  if (haveto == MHD_YES)
+    tv = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
+                                        timeout);
+  else
+    tv = GNUNET_TIME_UNIT_FOREVER_REL;
+  GNUNET_NETWORK_fdset_copy_native (wrs,
+                                    &rs,
+                                    max + 1);
+  GNUNET_NETWORK_fdset_copy_native (wws,
+                                    &ws,
+                                    max + 1);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding run_daemon select task\n");
+  ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                     tv,
+                                     wrs,
+                                     wws,
+                                     &run_daemon,
+                                     NULL);
+  GNUNET_NETWORK_fdset_destroy (wrs);
+  GNUNET_NETWORK_fdset_destroy (wws);
+  return ret;
+}
+
+
+void
+TALER_MHD_daemon_start (struct MHD_Daemon *daemon)
+{
+  GNUNET_assert (NULL == mhd);
+  mhd = daemon;
+  mhd_task = prepare_daemon ();
+}
+
+
+struct MHD_Daemon *
+TALER_MHD_daemon_stop (void)
+{
+  struct MHD_Daemon *ret;
+
+  if (NULL != mhd_task)
+  {
+    GNUNET_SCHEDULER_cancel (mhd_task);
+    mhd_task = NULL;
+  }
+  ret = mhd;
+  mhd = NULL;
+  return ret;
+}
+
+
+void
+TALER_MHD_daemon_trigger (void)
+{
+  if (NULL != mhd_task)
+  {
+    GNUNET_SCHEDULER_cancel (mhd_task);
+    mhd_task = NULL;
+    run_daemon (NULL);
+  }
+  else
+  {
+    triggered = 1;
+  }
+}
+
+
+/* end of mhd_run.c */
diff --git a/src/testing/test_taler_exchange_aggregator.c 
b/src/testing/test_taler_exchange_aggregator.c
index 2b3d642e..684fe969 100644
--- a/src/testing/test_taler_exchange_aggregator.c
+++ b/src/testing/test_taler_exchange_aggregator.c
@@ -41,7 +41,7 @@ static struct TALER_TESTING_ExchangeConfiguration ec;
 static struct TALER_TESTING_BankConfiguration bc;
 
 /**
- * Contains plugin and session.
+ * Contains plugin.
  */
 static struct TALER_TESTING_DatabaseConnection dbc;
 
@@ -499,8 +499,14 @@ prepare_database (void *cls,
     TALER_TESTING_interpreter_fail (is);
     return;
   }
-  dbc.session = dbc.plugin->get_session (dbc.plugin->cls);
-  GNUNET_assert (NULL != dbc.session);
+  if (GNUNET_OK !=
+      dbc.plugin->preflight (dbc.plugin->cls))
+  {
+    GNUNET_break (0);
+    result = 77;
+    TALER_TESTING_interpreter_fail (is);
+    return;
+  }
   GNUNET_SCHEDULER_add_shutdown (&unload_db,
                                  NULL);
   run (NULL,
diff --git a/src/testing/testing_api_cmd_insert_deposit.c 
b/src/testing/testing_api_cmd_insert_deposit.c
index b614702a..0d57ab6c 100644
--- a/src/testing/testing_api_cmd_insert_deposit.c
+++ b/src/testing/testing_api_cmd_insert_deposit.c
@@ -149,16 +149,13 @@ insert_deposit_run (void *cls,
 
   if ( (GNUNET_OK !=
         ids->dbc->plugin->start (ids->dbc->plugin->cls,
-                                 ids->dbc->session,
                                  "talertestinglib: denomination insertion")) ||
        (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
         ids->dbc->plugin->insert_denomination_info (ids->dbc->plugin->cls,
-                                                    ids->dbc->session,
                                                     &dpk,
                                                     &issue)) ||
        (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-        ids->dbc->plugin->commit (ids->dbc->plugin->cls,
-                                  ids->dbc->session)) )
+        ids->dbc->plugin->commit (ids->dbc->plugin->cls)) )
   {
     TALER_TESTING_interpreter_fail (is);
     return;
@@ -228,24 +225,19 @@ insert_deposit_run (void *cls,
   /* finally, actually perform the DB operation */
   if ( (GNUNET_OK !=
         ids->dbc->plugin->start (ids->dbc->plugin->cls,
-                                 ids->dbc->session,
                                  "libtalertesting: insert deposit")) ||
        (0 >
         ids->dbc->plugin->ensure_coin_known (ids->dbc->plugin->cls,
-                                             ids->dbc->session,
                                              &deposit.coin)) ||
        (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
         ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls,
-                                          ids->dbc->session,
                                           ids->exchange_timestamp,
                                           &deposit)) ||
        (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
-        ids->dbc->plugin->commit (ids->dbc->plugin->cls,
-                                  ids->dbc->session)) )
+        ids->dbc->plugin->commit (ids->dbc->plugin->cls)) )
   {
     GNUNET_break (0);
-    ids->dbc->plugin->rollback (ids->dbc->plugin->cls,
-                                ids->dbc->session);
+    ids->dbc->plugin->rollback (ids->dbc->plugin->cls);
     TALER_TESTING_interpreter_fail (is);
   }
 
@@ -302,7 +294,7 @@ insert_deposit_traits (void *cls,
  * Make the "insert-deposit" CMD.
  *
  * @param label command label.
- * @param dbc collects database plugin and session handles.
+ * @param dbc collects database plugin
  * @param merchant_name Human-readable name of the merchant.
  * @param merchant_account merchant's account name (NOT a payto:// URI)
  * @param exchange_timestamp when did the exchange receive the deposit
diff --git a/src/testing/testing_api_cmd_status.c 
b/src/testing/testing_api_cmd_status.c
index f395af28..6acfcc75 100644
--- a/src/testing/testing_api_cmd_status.c
+++ b/src/testing/testing_api_cmd_status.c
@@ -356,6 +356,7 @@ status_run (void *cls,
   }
   ss->rsh = TALER_EXCHANGE_reserves_get (is->exchange,
                                          ss->reserve_pubp,
+                                         GNUNET_TIME_UNIT_ZERO,
                                          &reserve_status_cb,
                                          ss);
 }
diff --git a/src/testing/testing_api_helpers_exchange.c 
b/src/testing/testing_api_helpers_exchange.c
index 8a4d71c5..a6307ca4 100644
--- a/src/testing/testing_api_helpers_exchange.c
+++ b/src/testing/testing_api_helpers_exchange.c
@@ -559,7 +559,8 @@ TALER_TESTING_wait_auditor_ready (const char *base_url)
                    base_url); // make sure ends with '/'
   /* give child time to start and bind against the socket */
   fprintf (stderr,
-           "Waiting for `taler-auditor-httpd' to be ready\n");
+           "Waiting for `taler-auditor-httpd' to be ready at %s\n",
+           base_url);
   iter = 0;
   do
   {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]