userver: userver/ydb/transaction.hpp Source File
Loading...
Searching...
No Matches
transaction.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/ydb/transaction.hpp
4/// @brief YDB transaction and retry transaction actor
5
6#include <functional>
7#include <string>
8
9#include <ydb-cpp-sdk/client/query/client.h>
10#include <ydb-cpp-sdk/client/table/table.h>
11
12#include <userver/engine/deadline.hpp>
13#include <userver/tracing/span.hpp>
14#include <userver/utils/function_ref.hpp>
15#include <userver/utils/trx_tracker.hpp>
16
17#include <userver/ydb/builder.hpp>
18#include <userver/ydb/exceptions.hpp>
19#include <userver/ydb/impl/stats_scope.hpp>
20#include <userver/ydb/query.hpp>
21#include <userver/ydb/response.hpp>
22#include <userver/ydb/settings.hpp>
23
24USERVER_NAMESPACE_BEGIN
25
26namespace ydb {
27
28class TxActor;
29
30/// Action to take after the retry function completes.
31enum class TxAction {
32 kCommit,
33 kRollback,
34};
35
36/// Signature for the function passed to TableClient::RetryTx.
37using RetryTxFunction = utils::function_ref<TxAction(TxActor&)>;
38
39/// @brief Transaction actor for use with TableClient::RetryTx.
40///
41/// Provides only query execution within a transaction. Commit and rollback
42/// are controlled by returning TxAction from the retry function.
43/// https://ydb.tech/docs/en/concepts/transactions
44class TxActor {
45public:
46 TxActor(const TxActor&) = delete;
47 TxActor& operator=(const TxActor&) = delete;
48 TxActor(TxActor&&) noexcept = delete;
49 TxActor& operator=(TxActor&&) = delete;
50
51 /// Execute a single data query as a part of the transaction. Query parameters
52 /// are passed in `Args` as "string key - value" pairs:
53 ///
54 /// @code
55 /// tx.Execute(query, "name1", value1, "name2", value2, ...);
56 /// @endcode
57 ///
58 /// Use ydb::PreparedArgsBuilder for storing a generic buffer of query params
59 /// if needed.
60 ///
61 /// @{
62 template <typename... Args>
63 ExecuteResponse Execute(const Query& query, Args&&... args);
64
65 template <typename... Args>
66 ExecuteResponse Execute(ExecuteSettings settings, const Query& query, Args&&... args);
67
68 ExecuteResponse Execute(ExecuteSettings settings, const Query& query, PreparedArgsBuilder&& builder);
69 /// @}
70
71 PreparedArgsBuilder GetBuilder() const;
72
73private:
74 friend class TableClient;
75
76 TxActor(
77 TableClient& table_client,
78 NYdb::NQuery::TSession& session,
79 NYdb::NQuery::TTxSettings&& tx_settings,
80 engine::Deadline deadline,
81 std::uint32_t attempt
82 ) noexcept;
83
84 NYdb::NQuery::TTransaction BeginTx(NYdb::NQuery::TSession& session, NYdb::NQuery::TTxSettings&& tx_settings);
85
86 template <TxAction Action>
87 void FinishTx(const RequestSettings& settings);
88
89 TableClient& table_client_;
90 engine::Deadline deadline_;
91 std::uint32_t attempt_;
92
93 NYdb::NQuery::TTransaction ydb_tx_;
94};
95
96template <typename... Args>
97ExecuteResponse TxActor::Execute(const Query& query, Args&&... args) {
98 auto builder = GetBuilder();
99 builder.AddParams(std::forward<Args>(args)...);
100 return Execute(ExecuteSettings{}, query, std::move(builder));
101}
102
103template <typename... Args>
104ExecuteResponse TxActor::Execute(ExecuteSettings settings, const Query& query, Args&&... args) {
105 auto builder = GetBuilder();
106 builder.AddParams(std::forward<Args>(args)...);
107 return Execute(std::move(settings), query, std::move(builder));
108}
109
110/// @brief YDB Transaction
111///
112/// @deprecated Use TableClient::RetryTx instead of manually managing
113/// transactions with Begin/Commit/Rollback.
114///
115/// https://ydb.tech/docs/en/concepts/transactions
116class Transaction final {
117public:
118 Transaction(Transaction&&) noexcept = default;
119 Transaction(const Transaction&) = delete;
120 Transaction& operator=(Transaction&&) = delete;
121 Transaction& operator=(const Transaction&) = delete;
122 ~Transaction();
123
124 /// Execute a single data query as a part of the transaction. Query parameters
125 /// are passed in `Args` as "string key - value" pairs:
126 ///
127 /// @code
128 /// client.ExecuteDataQuery(query, "name1", value1, "name2", value2, ...);
129 /// @endcode
130 ///
131 /// Use ydb::PreparedArgsBuilder for storing a generic buffer of query params
132 /// if needed.
133 ///
134 /// @{
135 template <typename... Args>
136 ExecuteResponse Execute(const Query& query, Args&&... args);
137
138 template <typename... Args>
139 ExecuteResponse Execute(OperationSettings settings, const Query& query, Args&&... args);
140
141 ExecuteResponse Execute(OperationSettings settings, const Query& query, PreparedArgsBuilder&& builder);
142
143 ExecuteResponse Execute(
144 QuerySettings query_settings,
145 OperationSettings settings,
146 const Query& query,
147 PreparedArgsBuilder&& builder
148 );
149 /// @}
150
151 /// Commit the transaction. The options that are missing in `settings` are
152 /// taken from the static config or driver defaults. `settings` can be
153 /// overridden by dynamic config's options for `Commit` "query".
154 void Commit(OperationSettings settings = {});
155
156 /// Rollback the transaction. The operation settings are taken from `Begin`
157 /// settings.
158 void Rollback();
159
160 PreparedArgsBuilder GetBuilder() const;
161
162 /// @cond
163 // For internal use only.
164 Transaction(
165 TableClient& table_client,
166 std::variant<NYdb::NQuery::TTransaction, NYdb::NTable::TTransaction> ydb_tx,
167 std::string name,
168 OperationSettings&& rollback_settings
169 ) noexcept;
170 /// @endcond
171
172 /// Get native transaction
173 /// @warning Use with care! Facilities from
174 /// `<core/include/userver/drivers/subscribable_futures.hpp>` can help with
175 /// non-blocking wait operations.
176 NYdb::TTransactionBase& GetNativeTransaction();
177
178private:
179 void MarkError() noexcept;
180 auto ErrorGuard();
181
182 void EnsureActive() const;
183
184 TableClient& table_client_;
185 std::string name_;
186 impl::StatsScope stats_scope_;
187 tracing::Span span_;
188 std::variant<NYdb::NQuery::TTransaction, NYdb::NTable::TTransaction> ydb_tx_;
189 OperationSettings rollback_settings_;
190 bool is_active_{true};
191 utils::trx_tracker::TransactionLock trx_lock_;
192};
193
194template <typename... Args>
195ExecuteResponse Transaction::Execute(const Query& query, Args&&... args) {
196 auto builder = GetBuilder();
197 builder.AddParams(std::forward<Args>(args)...);
198 return Execute(OperationSettings{}, query, std::move(builder));
199}
200
201template <typename... Args>
202ExecuteResponse Transaction::Execute(OperationSettings settings, const Query& query, Args&&... args) {
203 auto builder = GetBuilder();
204 builder.AddParams(std::forward<Args>(args)...);
205 return Execute(std::move(settings), query, std::move(builder));
206}
207
208} // namespace ydb
209
210USERVER_NAMESPACE_END