userver: /data/code/userver/odbc/include/userver/storages/odbc/transaction.hpp Source File
Loading...
Searching...
No Matches
transaction.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/odbc/transaction.hpp
4
5#include <chrono>
6
7#include <userver/engine/deadline.hpp>
8#include <userver/tracing/span.hpp>
9#include <userver/utils/datetime/steady_coarse_clock.hpp>
10#include <userver/utils/fast_pimpl.hpp>
11#include <userver/utils/trx_tracker.hpp>
12
13#include <userver/storages/odbc/bulk.hpp>
14#include <userver/storages/odbc/command_control.hpp>
15#include <userver/storages/odbc/cursor.hpp>
16#include <userver/storages/odbc/impl/parameter.hpp>
17#include <userver/storages/odbc/parameter_store.hpp>
18#include <userver/storages/odbc/query.hpp>
19#include <userver/storages/odbc/result_set.hpp>
20#include <userver/storages/odbc/transaction_options.hpp>
21
22USERVER_NAMESPACE_BEGIN
23
24namespace storages::odbc {
25
26namespace detail {
27struct BulkLayout;
28class ConnectionPtr;
29class Pool;
30} // namespace detail
31
32/// @brief RAII transaction wrapper, auto-<b>ROLLBACK</b>s on destruction if no
33/// prior `Commit`/`Rollback` call was made.
34///
35/// This type can't be constructed in user code and is always retrieved from
36/// storages::odbc::Cluster
37class Transaction final {
38public:
39 explicit Transaction(
40 detail::ConnectionPtr&& connection,
41 detail::Pool& pool,
42 std::chrono::milliseconds network_timeout,
43 std::chrono::milliseconds statement_timeout
44 );
45 explicit Transaction(
46 detail::ConnectionPtr&& connection,
47 detail::Pool& pool,
48 const TransactionOptions& options,
49 std::chrono::milliseconds network_timeout,
50 std::chrono::milliseconds statement_timeout
51 );
52 ~Transaction();
53 Transaction(const Transaction& other) = delete;
54 Transaction(Transaction&& other) noexcept;
55
56 /// @brief Execute a statement, binding every argument to an ODBC `?` placeholder.
57 template <typename... Args>
58 requires((impl::kIsParameterArgument<Args> && ...))
59 ResultSet Execute(const Query& query, const Args&... args) {
60 return Execute(std::nullopt, query, args...);
61 }
62
63 /// @brief Execute a statement with per-statement timeout overrides.
64 template <typename... Args>
65 requires((impl::kIsParameterArgument<Args> && ...))
66 ResultSet Execute(OptionalCommandControl command_control, const Query& query, const Args&... args) {
67 return DoExecute(command_control, query, impl::MakeParameterList(args...));
68 }
69
70 /// @brief Execute a statement with an owning dynamic parameter list.
71 ResultSet Execute(const Query& query, const ParameterStore& store);
72
73 /// @brief Execute a statement with a dynamic parameter list and timeout overrides.
74 ResultSet Execute(OptionalCommandControl command_control, const Query& query, const ParameterStore& store);
75
76 /// @brief Execute a row-producing statement as an incremental cursor.
77 ///
78 /// No other transaction operation is allowed until the cursor observes EOF
79 /// or is destroyed.
80 template <typename... Args>
81 requires((impl::kIsParameterArgument<Args> && ...))
82 Cursor ExecuteCursor(const Query& query, const Args&... args) {
83 return ExecuteCursor(std::nullopt, query, args...);
84 }
85
86 template <typename... Args>
87 requires((impl::kIsParameterArgument<Args> && ...))
88 Cursor ExecuteCursor(OptionalCommandControl command_control, const Query& query, const Args&... args) {
89 return DoExecuteCursor(command_control, query, impl::MakeParameterList(args...));
90 }
91
92 Cursor ExecuteCursor(const Query& query, const ParameterStore& store);
93
94 Cursor ExecuteCursor(OptionalCommandControl command_control, const Query& query, const ParameterStore& store);
95
96 /// Execute rows as bounded chunks of DML that must not return result sets.
97 /// On failure, inspect BulkExecutionError and roll back the transaction.
98 BulkResult ExecuteBulk(
99 const Query& query,
100 const BulkParameterStore& rows,
101 std::size_t chunk_rows = kDefaultBulkRows
102 );
103
104 /// Execute bulk DML with per-operation timeout overrides.
105 BulkResult ExecuteBulk(
106 OptionalCommandControl command_control,
107 const Query& query,
108 const BulkParameterStore& rows,
109 std::size_t chunk_rows = kDefaultBulkRows
110 );
111
112 /// @brief Commit the transaction
113 void Commit();
114
115 /// @brief Rollback the transaction
116 void Rollback();
117
118private:
119 ResultSet DoExecute(
120 OptionalCommandControl command_control,
121 const Query& query,
122 const impl::ParameterList& parameters
123 );
124 Cursor DoExecuteCursor(
125 OptionalCommandControl command_control,
126 const Query& query,
127 const impl::ParameterList& parameters
128 );
129 BulkResult DoExecuteBulk(
130 OptionalCommandControl command_control,
131 const Query& query,
132 const impl::ParameterRows& rows,
133 const detail::BulkLayout& layout,
134 std::size_t chunk_rows
135 );
136 void AssertValid() const;
137
138 // shared_ptr<Pool>(16) + unique_ptr<Connection>(8) = 24 bytes, align 8
139 utils::FastPimpl<detail::ConnectionPtr, 24, 8> connection_;
140 detail::Pool* pool_;
141 std::chrono::milliseconds network_timeout_;
142 std::chrono::milliseconds statement_timeout_;
143 utils::datetime::SteadyCoarseClock::time_point start_time_;
144 std::chrono::microseconds busy_time_{0};
145 tracing::Span span_;
146 utils::trx_tracker::TransactionLock trx_lock_;
147};
148
149} // namespace storages::odbc
150
151USERVER_NAMESPACE_END