libpqxx
The C++ client library for PostgreSQL
 
Loading...
Searching...
No Matches
transactor.hxx
1/* Transactor framework, a wrapper for safely retryable transactions.
2 *
3 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead.
4 *
5 * Copyright (c) 2000-2024, Jeroen T. Vermeulen.
6 *
7 * See COPYING for copyright license. If you did not receive a file called
8 * COPYING with this source code, please notify the distributor of this
9 * mistake, or contact the author.
10 */
11#ifndef PQXX_H_TRANSACTOR
12#define PQXX_H_TRANSACTOR
13
14#if !defined(PQXX_HEADER_PRE)
15# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
16#endif
17
18#include <functional>
19#include <type_traits>
20
21#include "pqxx/connection.hxx"
22#include "pqxx/transaction.hxx"
23
24namespace pqxx
25{
68
70
99template<typename TRANSACTION_CALLBACK>
100inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3)
101 -> std::invoke_result_t<TRANSACTION_CALLBACK>
102{
103 if (attempts <= 0)
104 throw std::invalid_argument{
105 "Zero or negative number of attempts passed to pqxx::perform()."};
106
107 for (; attempts > 0; --attempts)
108 {
109 try
110 {
111 return std::invoke(callback);
112 }
113 catch (in_doubt_error const &)
114 {
115 // Not sure whether transaction went through or not. The last thing in
116 // the world that we should do now is try again!
117 throw;
118 }
119 catch (statement_completion_unknown const &)
120 {
121 // Not sure whether our last statement succeeded. Don't risk running it
122 // again.
123 throw;
124 }
125 catch (protocol_violation const &)
126 {
127 // This is a subclass of broken_connection, but it's not one where
128 // retrying is likely to do us any good.
129 throw;
130 }
131 catch (broken_connection const &)
132 {
133 // Connection failed. May be worth retrying, if the transactor opens its
134 // own connection.
135 if (attempts <= 1)
136 throw;
137 continue;
138 }
139 catch (transaction_rollback const &)
140 {
141 // Some error that may well be transient, such as serialization failure
142 // or deadlock. Worth retrying.
143 if (attempts <= 1)
144 throw;
145 continue;
146 }
147 }
148 throw pqxx::internal_error{"No outcome reached on perform()."};
149}
150} // namespace pqxx
152#endif
Exception class for lost or failed backend connection.
Definition except.hxx:81
"Help, I don't know whether transaction was committed successfully!"
Definition except.hxx:165
Internal error in libpqxx library.
Definition except.hxx:242
Exception class for micommunication with the server.
Definition except.hxx:103
We can't tell whether our last statement succeeded.
Definition except.hxx:214
The backend saw itself forced to roll back the ongoing transaction.
Definition except.hxx:178
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
auto perform(TRANSACTION_CALLBACK &&callback, int attempts=3) -> std::invoke_result_t< TRANSACTION_CALLBACK >
Simple way to execute a transaction with automatic retry.
Definition transactor.hxx:100