LCOV - code coverage report
Current view: top level - exchangedb - commit.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 16 16
Test Date: 2026-09-11 18:55:36 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /*
       2              :    This file is part of TALER
       3              :    Copyright (C) 2022 Taler Systems SA
       4              : 
       5              :    TALER is free software; you can redistribute it and/or modify it under the
       6              :    terms of the GNU General Public License as published by the Free Software
       7              :    Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12              : 
      13              :    You should have received a copy of the GNU General Public License along with
      14              :    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              :  */
      16              : /**
      17              :  * @file exchangedb/commit.c
      18              :  * @brief Implementation of the commit function for Postgres
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "taler/taler_pq_lib.h"
      22              : #include "exchange-database/commit.h"
      23              : #include "helper.h"
      24              : 
      25              : 
      26              : enum GNUNET_DB_QueryStatus
      27         1026 : TALER_EXCHANGEDB_commit (struct TALER_EXCHANGEDB_PostgresContext *pg)
      28              : {
      29         1026 :   struct GNUNET_PQ_QueryParam params[] = {
      30              :     GNUNET_PQ_query_param_end
      31              :   };
      32              :   enum GNUNET_DB_QueryStatus qs;
      33              : 
      34         1026 :   GNUNET_break (NULL != pg->transaction_name);
      35         1026 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
      36              :               "Committing transaction `%s'\n",
      37              :               pg->transaction_name);
      38         1026 :   PREPARE (pg,
      39              :            "commit",
      40              :            "COMMIT");
      41              :   {
      42              :     PGresult *result;
      43              : 
      44         1026 :     result = GNUNET_PQ_exec_prepared (pg->conn,
      45              :                                       "commit",
      46              :                                       params);
      47         1026 :     qs = GNUNET_PQ_eval_result (pg->conn,
      48              :                                 "commit",
      49              :                                 result);
      50         1026 :     if ( (0 <= qs) &&
      51         1026 :          (NULL != result) &&
      52         1026 :          (0 == strcmp ("ROLLBACK",
      53         1026 :                        PQcmdStatus (result))) )
      54              :     {
      55              :       /* PostgreSQL accepts COMMIT on a transaction it has already aborted:
      56              :          it silently rolls back and answers PGRES_COMMAND_OK with the command
      57              :          tag ROLLBACK.  That is indistinguishable from a successful commit to
      58              :          GNUNET_PQ_eval_result(), so every caller would take the success path
      59              :          for a transaction whose writes are gone.  Report it as a soft error:
      60              :          the transaction is almost always aborted by a serialization failure
      61              :          (we run SERIALIZABLE), so retrying is the right answer, and callers
      62              :          with a retry loop will give up and fail visibly after
      63              :          MAX_RETRIES. */
      64            1 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
      65              :                   "Transaction `%s' was rolled back by the database instead of committed; a previous statement must have failed without being handled\n",
      66              :                   pg->transaction_name);
      67            1 :       qs = GNUNET_DB_STATUS_SOFT_ERROR;
      68              :     }
      69         1026 :     PQclear (result);
      70              :   }
      71         1026 :   pg->transaction_name = NULL;
      72         1026 :   return qs;
      73              : }
        

Generated by: LCOV version 2.0-1