aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
diff options
context:
space:
mode:
authorgalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 11:26:33 +0300
committergalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 12:01:57 +0300
commit44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch)
treecb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
parent0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff)
downloadydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz
YQ Connector:test INNER JOIN
Diffstat (limited to 'contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx')
-rw-r--r--contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx168
1 files changed, 168 insertions, 0 deletions
diff --git a/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx b/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
new file mode 100644
index 0000000000..c4c16323b1
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
@@ -0,0 +1,168 @@
+/** Definition of the pqxx::robusttransaction class.
+ *
+ * pqxx::robusttransaction is a slower but safer transaction class.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead.
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+#ifndef PQXX_H_ROBUSTTRANSACTION
+#define PQXX_H_ROBUSTTRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/dbtransaction.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+
+namespace internal
+{
+/// Helper base class for the @c robusttransaction class template.
+class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction :
+ public dbtransaction
+{
+public:
+ /// Isolation level is read_committed by default.
+ using isolation_tag = isolation_traits<read_committed>;
+
+ virtual ~basic_robusttransaction() =0; //[t16]
+
+protected:
+ basic_robusttransaction(
+ connection_base &C,
+ const std::string &IsolationLevel,
+ const std::string &table_name=std::string{}); //[t16]
+
+private:
+ using IDType = unsigned long;
+ IDType m_record_id = 0;
+ std::string m_xid;
+ std::string m_log_table;
+ std::string m_sequence;
+ int m_backendpid = -1;
+
+ virtual void do_begin() override; //[t18]
+ virtual void do_commit() override; //[t16]
+ virtual void do_abort() override; //[t18]
+
+ PQXX_PRIVATE void CreateLogTable();
+ PQXX_PRIVATE void CreateTransactionRecord();
+ PQXX_PRIVATE std::string sql_delete() const;
+ PQXX_PRIVATE void DeleteTransactionRecord() noexcept;
+ PQXX_PRIVATE bool CheckTransactionRecord();
+};
+} // namespace internal
+
+
+/**
+ * @ingroup transaction
+ *
+ * @{
+ */
+
+/// Slightly slower, better-fortified version of transaction
+/** robusttransaction is similar to transaction, but spends more effort (and
+ * performance!) to deal with the hopefully rare case that the connection to
+ * the backend is lost just as the current transaction is being committed. In
+ * this case, there is no way to determine whether the backend managed to
+ * commit the transaction before noticing the loss of connection.
+ *
+ * In such cases, this class tries to reconnect to the database and figure out
+ * what happened. It will need to store and manage some information (pretty
+ * much a user-level transaction log) in the back-end for each and every
+ * transaction just on the off chance that this problem might occur.
+ * This service level was made optional since you may not want to pay this
+ * overhead where it is not necessary. Certainly the use of this class makes
+ * no sense for local connections, or for transactions that read the database
+ * but never modify it, or for noncritical database manipulations.
+ *
+ * Besides being slower, it's theoretically possible that robusttransaction
+ * actually fails more instead of less often than a normal transaction. This is
+ * due to the added work and complexity. What robusttransaction tries to
+ * achieve is to be more deterministic, not more successful per se.
+ *
+ * When a user first uses a robusttransaction in a database, the class will
+ * attempt to create a log table there to keep vital transaction-related state
+ * information in. This table, located in that same database, will be called
+ * pqxxlog_*user*, where *user* is the PostgreSQL username for that user. If
+ * the log table can not be created, the transaction fails immediately.
+ *
+ * If the user does not have permission to create the log table, the database
+ * administrator may create one for him beforehand, and give ownership (or at
+ * least full insert/update rights) to the user. The table must contain two
+ * non-unique fields (which will never be null): "name" (of text type,
+ * @c varchar(256) by default) and "date" (of @c timestamp type). Older
+ * versions of robusttransaction also added a unique "id" field; this field is
+ * now obsolete and the log table's implicit oids are used instead. The log
+ * tables' names may be made configurable in a future version of libpqxx.
+ *
+ * The transaction log table contains records describing unfinished
+ * transactions, i.e. ones that have been started but not, as far as the client
+ * knows, committed or aborted. This can mean any of the following:
+ *
+ * <ol>
+ * <li> The transaction is in progress. Since backend transactions can't run
+ * for extended periods of time, this can only be the case if the log record's
+ * timestamp (compared to the server's clock) is not very old, provided of
+ * course that the server's system clock hasn't just made a radical jump.
+ * <li> The client's connection to the server was lost, just when the client was
+ * committing the transaction, and the client so far has not been able to
+ * re-establish the connection to verify whether the transaction was actually
+ * completed or rolled back by the server. This is a serious (and luckily a
+ * rare) condition and requires manual inspection of the database to determine
+ * what happened. The robusttransaction will emit clear and specific warnings
+ * to this effect, and will identify the log record describing the transaction
+ * in question.
+ * <li> The transaction was completed (either by commit or by rollback), but the
+ * client's connection was durably lost just as it tried to clean up the log
+ * record. Again, robusttransaction will emit a clear and specific warning to
+ * tell you about this and request that the record be deleted as soon as
+ * possible.
+ * <li> The client has gone offline at any time while in one of the preceding
+ * states. This also requires manual intervention, but the client obviously is
+ * not able to issue a warning.
+ * </ol>
+ *
+ * It is safe to drop a log table when it is not in use (ie., it is empty or all
+ * records in it represent states 2-4 above). Each robusttransaction will
+ * attempt to recreate the table at its next time of use.
+ */
+template<isolation_level ISOLATIONLEVEL=read_committed>
+class robusttransaction : public internal::basic_robusttransaction
+{
+public:
+ using isolation_tag = isolation_traits<ISOLATIONLEVEL>;
+
+ /// Constructor
+ /** Creates robusttransaction of given name
+ * @param C Connection that this robusttransaction should live inside.
+ * @param Name optional human-readable name for this transaction
+ */
+ explicit robusttransaction(
+ connection_base &C,
+ const std::string &Name=std::string{}) :
+ namedclass{fullname("robusttransaction",isolation_tag::name()), Name},
+ internal::basic_robusttransaction(C, isolation_tag::name())
+ { Begin(); }
+
+ virtual ~robusttransaction() noexcept
+ { End(); }
+};
+
+/**
+ * @}
+ */
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif