diff options
author | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 11:26:33 +0300 |
---|---|---|
committer | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 12:01:57 +0300 |
commit | 44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch) | |
tree | cb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx | |
parent | 0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff) | |
download | ydb-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.hxx | 168 |
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 |