Google Cloud Spanner C++ Client 2.13.0
A C++ Client Library for Google Cloud Spanner
Loading...
Searching...
No Matches
transaction.h
1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TRANSACTION_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TRANSACTION_H
17
18#include "google/cloud/spanner/internal/transaction_impl.h"
19#include "google/cloud/spanner/timestamp.h"
20#include "google/cloud/spanner/version.h"
21#include "absl/types/optional.h"
22#include <google/spanner/v1/transaction.pb.h>
23#include <chrono>
24#include <memory>
25#include <string>
26
27namespace google {
28namespace cloud {
29namespace spanner_internal {
30GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
31struct TransactionInternals;
32GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
33} // namespace spanner_internal
34
35namespace spanner {
36GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
37
38/**
39 * The representation of a Cloud Spanner transaction.
40 *
41 * A transaction is a set of reads and writes that execute atomically at a
42 * single logical point in time across the columns/rows/tables in a database.
43 * Those reads and writes are grouped by passing them the same `Transaction`.
44 *
45 * All reads/writes in the transaction must be executed within the same
46 * session, and that session may have only one transaction active at a time.
47 *
48 * Spanner supports these transaction modes:
49 * - ReadOnly. Provides guaranteed consistency across several reads, but does
50 * not allow writes. Can be configured to read at timestamps in the past.
51 * Does not need to be committed and does not take locks.
52 * - ReadWrite. Supports reading and writing data at a single point in time.
53 * Uses pessimistic locking and, if necessary, two-phase commit. May abort,
54 * requiring the application to rerun.
55 * - SingleUse. A restricted form of a ReadOnly transaction where Spanner
56 * chooses the read timestamp.
57 */
58class Transaction {
59 public:
60 /**
61 * Options for ReadOnly transactions.
62 */
63 class ReadOnlyOptions {
64 public:
65 // Strong: Guarantees visibility of the effects of all transactions that
66 // committed before the start of the reads.
68
69 // Exact Staleness: Executes all reads at `read_timestamp`.
70 explicit ReadOnlyOptions(Timestamp read_timestamp);
71
72 // Exact Staleness: Executes all reads at a timestamp `exact_staleness`
73 // old. The actual timestamp is chosen soon after the reads are started.
74 explicit ReadOnlyOptions(std::chrono::nanoseconds exact_staleness);
75
76 private:
77 friend Transaction;
78 google::spanner::v1::TransactionOptions_ReadOnly ro_opts_;
79 };
80
81 /**
82 * Options for ReadWrite transactions.
83 */
84 class ReadWriteOptions {
85 public:
86 // There are currently no read-write options.
88
89 // A tag used for collecting statistics about the transaction.
90 ReadWriteOptions& WithTag(absl::optional<std::string> tag);
91
92 private:
93 friend Transaction;
94 google::spanner::v1::TransactionOptions_ReadWrite rw_opts_;
95 absl::optional<std::string> tag_;
96 };
97
98 /**
99 * Options for "single-use", ReadOnly transactions, where Spanner chooses
100 * the read timestamp, subject to user-provided bounds. This allows reading
101 * without blocking.
102 *
103 * Because selection of the timestamp requires knowledge of which rows will
104 * be read, a single-use transaction can only be used with one read. See
105 * Client::Read() and Client::ExecuteQuery(). SingleUseOptions cannot be used
106 * to construct an application-level Transaction.
107 */
108 class SingleUseOptions {
109 public:
110 // Strong or Exact Staleness: See ReadOnlyOptions.
111 // NOLINTNEXTLINE(google-explicit-constructor)
113
114 // Bounded Staleness: Executes all reads at a timestamp that is not
115 // before `min_read_timestamp`.
116 explicit SingleUseOptions(Timestamp min_read_timestamp);
117
118 // Bounded Staleness: Executes all reads at a timestamp that is not
119 // before `NOW - max_staleness`.
120 explicit SingleUseOptions(std::chrono::nanoseconds max_staleness);
121
122 private:
123 friend Transaction;
124 google::spanner::v1::TransactionOptions_ReadOnly ro_opts_;
125 };
126
127 /// @name Construction of read-only and read-write transactions.
128 ///@{
129 /**
130 * @note This is a lazy evaluated operation. No RPCs are made as part of
131 * creating a `Transaction` object. Instead, the first request to the
132 * server (for example as part of a `ExecuteQuery()` call) will also
133 * create the transaction.
134 */
135 explicit Transaction(ReadOnlyOptions opts);
136 /// @copydoc Transaction(ReadOnlyOptions)
137 explicit Transaction(ReadWriteOptions opts);
138 /// @copydoc Transaction(ReadOnlyOptions)
139 Transaction(Transaction const& txn, ReadWriteOptions opts);
140 ///@}
141
142 ~Transaction();
143
144 /// @name Regular value type, supporting copy, assign, move.
145 ///@{
146 Transaction(Transaction&&) = default;
147 Transaction& operator=(Transaction&&) = default;
148 Transaction(Transaction const&) = default;
149 Transaction& operator=(Transaction const&) = default;
150 ///@}
151
152 /// @name Equality operators
153 ///@{
154 friend bool operator==(Transaction const& a, Transaction const& b) {
155 return a.impl_ == b.impl_;
156 }
157 friend bool operator!=(Transaction const& a, Transaction const& b) {
158 return !(a == b);
159 }
160 ///@}
161
162 private:
163 // Friendship for access by internal helpers.
164 friend struct spanner_internal::TransactionInternals;
165 struct SingleUseCommitTag {};
166
167 // Construction of a single-use transaction.
168 explicit Transaction(SingleUseOptions opts);
169 // Construction of a single-use commit transaction.
170 Transaction(ReadWriteOptions opts, SingleUseCommitTag);
171 // Construction of a transaction with existing IDs.
172 Transaction(std::string session_id, std::string transaction_id,
173 bool route_to_leader, std::string transaction_tag);
174
175 std::shared_ptr<spanner_internal::TransactionImpl> impl_;
176};
177
178/**
179 * Create a read-only transaction configured with @p opts.
180 *
181 * @copydoc Transaction::Transaction(Transaction::ReadOnlyOptions)
182 */
185 return Transaction(std::move(opts));
186}
187
188/**
189 * Create a read-write transaction configured with @p opts.
190 *
191 * @copydoc Transaction::Transaction(Transaction::ReadOnlyOptions)
192 */
195 return Transaction(std::move(opts));
196}
197
198/**
199 * Create a read-write transaction configured with @p opts, and sharing
200 * lock priority with @p txn. This should be used when rerunning an aborted
201 * transaction, so that the new attempt has a slightly better chance of
202 * success.
203 */
205 Transaction const& txn, Transaction::ReadWriteOptions opts = {}) {
206 return Transaction(txn, std::move(opts));
207}
208
209GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
210} // namespace spanner
211
212namespace spanner_internal {
213GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
214
215struct TransactionInternals {
216 template <typename T>
217 static spanner::Transaction MakeSingleUseTransaction(T&& opts) {
218 // Requires that `opts` is implicitly convertible to SingleUseOptions.
219 spanner::Transaction::SingleUseOptions su_opts = std::forward<T>(opts);
220 return spanner::Transaction(std::move(su_opts));
221 }
222
223 static spanner::Transaction MakeSingleUseCommitTransaction(
225 return spanner::Transaction(std::move(opts),
226 spanner::Transaction::SingleUseCommitTag{});
227 }
228
229 template <typename Functor>
230 // Pass `txn` by value, despite being used only once. This avoids the
231 // possibility of `txn` being destroyed by `f` before `Visit()` can
232 // return. Therefore, ...
233 // NOLINTNEXTLINE(performance-unnecessary-value-param)
234 static VisitInvokeResult<Functor> Visit(spanner::Transaction txn,
235 Functor&& f) {
236 return txn.impl_->Visit(std::forward<Functor>(f));
237 }
238
239 static spanner::Transaction MakeTransactionFromIds(
240 std::string session_id, std::string transaction_id, bool route_to_leader,
241 std::string transaction_tag);
242};
243
244template <typename T>
245spanner::Transaction MakeSingleUseTransaction(T&& opts) {
246 return TransactionInternals::MakeSingleUseTransaction(std::forward<T>(opts));
247}
248
249inline spanner::Transaction MakeSingleUseCommitTransaction(
251 return TransactionInternals::MakeSingleUseCommitTransaction(std::move(opts));
252}
253
254template <typename Functor>
255// Pass `txn` by value, despite being used only once. This avoids the
256// possibility of `txn` being destroyed by `f` before `Visit()` can
257// return. Therefore, ...
258// NOLINTNEXTLINE(performance-unnecessary-value-param)
259VisitInvokeResult<Functor> Visit(spanner::Transaction txn, Functor&& f) {
260 return TransactionInternals::Visit(std::move(txn), std::forward<Functor>(f));
261}
262
263inline spanner::Transaction MakeTransactionFromIds(
264 std::string session_id, std::string transaction_id, bool route_to_leader,
265 std::string transaction_tag) {
266 return TransactionInternals::MakeTransactionFromIds(
267 std::move(session_id), std::move(transaction_id), route_to_leader,
268 std::move(transaction_tag));
269}
270
271GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
272} // namespace spanner_internal
273} // namespace cloud
274} // namespace google
275
276#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TRANSACTION_H
A representation of the Spanner TIMESTAMP type: An instant in time.
Definition: timestamp.h:54
Options for ReadOnly transactions.
Definition: transaction.h:63
ReadOnlyOptions(std::chrono::nanoseconds exact_staleness)
Options for ReadWrite transactions.
Definition: transaction.h:84
ReadWriteOptions & WithTag(absl::optional< std::string > tag)
Options for "single-use", ReadOnly transactions, where Spanner chooses the read timestamp,...
Definition: transaction.h:108
SingleUseOptions(std::chrono::nanoseconds max_staleness)
The representation of a Cloud Spanner transaction.
Definition: transaction.h:58
Transaction(Transaction &&)=default
Transaction & operator=(Transaction const &)=default
Transaction & operator=(Transaction &&)=default
friend bool operator==(Transaction const &a, Transaction const &b)
Definition: transaction.h:154
Transaction(Transaction const &)=default
Transaction(ReadWriteOptions opts)
Transaction(Transaction const &txn, ReadWriteOptions opts)
Transaction(ReadOnlyOptions opts)
friend bool operator!=(Transaction const &a, Transaction const &b)
Definition: transaction.h:157
Contains all the Cloud Spanner C++ client types and functions.
Definition: backoff_policy.h:23
Transaction MakeReadWriteTransaction(Transaction::ReadWriteOptions opts={})
Create a read-write transaction configured with opts.
Definition: transaction.h:193
Transaction MakeReadWriteTransaction(Transaction const &txn, Transaction::ReadWriteOptions opts={})
Create a read-write transaction configured with opts, and sharing lock priority with txn.
Definition: transaction.h:204
Transaction MakeReadOnlyTransaction(Transaction::ReadOnlyOptions opts={})
Create a read-only transaction configured with opts.
Definition: transaction.h:183