Google Cloud Spanner C++ Client 2.8.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
166 // Construction of a single-use transaction.
167 explicit Transaction(SingleUseOptions opts);
168 // Construction of a transaction with existing IDs.
169 Transaction(std::string session_id, std::string transaction_id,
170 bool route_to_leader, std::string transaction_tag);
171
172 std::shared_ptr<spanner_internal::TransactionImpl> impl_;
173};
174
175/**
176 * Create a read-only transaction configured with @p opts.
177 *
178 * @copydoc Transaction::Transaction(Transaction::ReadOnlyOptions)
179 */
182 return Transaction(std::move(opts));
183}
184
185/**
186 * Create a read-write transaction configured with @p opts.
187 *
188 * @copydoc Transaction::Transaction(Transaction::ReadOnlyOptions)
189 */
192 return Transaction(std::move(opts));
193}
194
195/**
196 * Create a read-write transaction configured with @p opts, and sharing
197 * lock priority with @p txn. This should be used when rerunning an aborted
198 * transaction, so that the new attempt has a slightly better chance of
199 * success.
200 */
202 Transaction const& txn, Transaction::ReadWriteOptions opts = {}) {
203 return Transaction(txn, std::move(opts));
204}
205
206GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
207} // namespace spanner
208
209namespace spanner_internal {
210GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
211
212struct TransactionInternals {
213 template <typename T>
214 static spanner::Transaction MakeSingleUseTransaction(T&& opts) {
215 // Requires that `opts` is implicitly convertible to SingleUseOptions.
216 spanner::Transaction::SingleUseOptions su_opts = std::forward<T>(opts);
217 return spanner::Transaction(std::move(su_opts));
218 }
219
220 template <typename Functor>
221 // Pass `txn` by value, despite being used only once. This avoids the
222 // possibility of `txn` being destroyed by `f` before `Visit()` can
223 // return. Therefore, ...
224 // NOLINTNEXTLINE(performance-unnecessary-value-param)
225 static VisitInvokeResult<Functor> Visit(spanner::Transaction txn,
226 Functor&& f) {
227 return txn.impl_->Visit(std::forward<Functor>(f));
228 }
229
230 static spanner::Transaction MakeTransactionFromIds(
231 std::string session_id, std::string transaction_id, bool route_to_leader,
232 std::string transaction_tag);
233};
234
235template <typename T>
236spanner::Transaction MakeSingleUseTransaction(T&& opts) {
237 return TransactionInternals::MakeSingleUseTransaction(std::forward<T>(opts));
238}
239
240template <typename Functor>
241// Pass `txn` by value, despite being used only once. This avoids the
242// possibility of `txn` being destroyed by `f` before `Visit()` can
243// return. Therefore, ...
244// NOLINTNEXTLINE(performance-unnecessary-value-param)
245VisitInvokeResult<Functor> Visit(spanner::Transaction txn, Functor&& f) {
246 return TransactionInternals::Visit(std::move(txn), std::forward<Functor>(f));
247}
248
249inline spanner::Transaction MakeTransactionFromIds(
250 std::string session_id, std::string transaction_id, bool route_to_leader,
251 std::string transaction_tag) {
252 return TransactionInternals::MakeTransactionFromIds(
253 std::move(session_id), std::move(transaction_id), route_to_leader,
254 std::move(transaction_tag));
255}
256
257GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
258} // namespace spanner_internal
259} // namespace cloud
260} // namespace google
261
262#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:190
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:201
Transaction MakeReadOnlyTransaction(Transaction::ReadOnlyOptions opts={})
Create a read-only transaction configured with opts.
Definition: transaction.h:180