Class Client (2.13.0)

Performs database client operations on Spanner.

Applications use this class to perform operations on Spanner Databases.

Performance

Client objects are relatively cheap to create, copy, and move. However, each Client object must be created with a std::shared_ptr<Connection>, which itself is relatively expensive to create. Therefore, connection instances should be shared when possible. See the MakeConnection() method and the Connection interface for more details.

Thread Safety

Instances of this class created via copy-construction or copy-assignment share the underlying pool of connections. Access to these copies via multiple threads is guaranteed to work. Two threads operating on the same instance of this class is not guaranteed to work.

Error Handling

This class uses StatusOr<T> to report errors. When an operation fails to perform its work the returned StatusOr<T> contains the error details. If the ok() member function in the StatusOr<T> returns true then it contains the expected result. For more information, see the Error Handling Guide.

namespace spanner = ::google::cloud::spanner;

auto db = spanner::Database("my_project", "my_instance", "my_db_id"));
auto conn = spanner::MakeConnection(db);
auto client = spanner::Client(conn);

auto rows = client.Read(...);
using RowType = std::tuple<std::int64_t, std::string>;
for (auto const& row : spanner::StreamOf<RowType>(rows)) {
  // ...
}
Query Options

Most operations that take an SqlStatement may also be modified with query Options. These options can be set at various levels, with more specific levels taking precedence over broader ones. For example, Options that are passed directly to Client::ExecuteQuery() will take precedence over the Client-level defaults (if any), which will themselves take precedence over any environment variables. The following table shows the environment variables that may optionally be set and the query Options setting that they affect.

Environment Variable Options setting
SPANNER_OPTIMIZER_VERSION QueryOptimizerVersionOption
SPANNER_OPTIMIZER_STATISTICS_PACKAGE QueryOptimizerStatisticsPackageOption
See Also

https://cloud.google.com/spanner/docs/reference/rest/v1/QueryOptions

See Also

http://cloud/spanner/docs/query-optimizer/manage-query-optimizer

Constructors

Client(Client const &)

Copy and move support

Parameter
Name Description
Client const &

Client(Client &&)

Copy and move support

Parameter
Name Description
Client &&

Client(std::shared_ptr< Connection >, ClientOptions const &)

Backwards compatibility for ClientOptions.

Parameters
Name Description
conn std::shared_ptr< Connection >
opts ClientOptions const &

Client(std::shared_ptr< Connection >, std::initializer_list< internal::NonConstructible >)

Backwards compatibility for ClientOptions.

Parameters
Name Description
conn std::shared_ptr< Connection >
std::initializer_list< internal::NonConstructible >

Client(std::shared_ptr< Connection >, Options)

Constructs a Client object using the specified conn and opts.

See MakeConnection() for how to create a connection to Spanner. To help with unit testing, callers may create fake/mock Connection objects that are injected into the Client.

Parameters
Name Description
conn std::shared_ptr< Connection >
opts Options

Client()

No default construction.

Operators

operator=(Client const &)

Copy and move support

Parameter
Name Description
Client const &
Returns
Type Description
Client &

operator=(Client &&)

Copy and move support

Parameter
Name Description
Client &&
Returns
Type Description
Client &

Functions

Read(std::string, KeySet, std::vector< std::string >, ReadOptions const &)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
table std::string
keys KeySet
columns std::vector< std::string >
read_options ReadOptions const &
Returns
Type Description
RowStream

Read(std::string, KeySet, std::vector< std::string >, std::initializer_list< internal::NonConstructible >)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
table std::string
keys KeySet
columns std::vector< std::string >
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

Read(Transaction::SingleUseOptions, std::string, KeySet, std::vector< std::string >, ReadOptions const &)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
table std::string
keys KeySet
columns std::vector< std::string >
read_options ReadOptions const &
Returns
Type Description
RowStream

Read(Transaction::SingleUseOptions, std::string, KeySet, std::vector< std::string >, std::initializer_list< internal::NonConstructible >)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
table std::string
keys KeySet
columns std::vector< std::string >
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

Read(Transaction, std::string, KeySet, std::vector< std::string >, ReadOptions const &)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
transaction Transaction
table std::string
keys KeySet
columns std::vector< std::string >
read_options ReadOptions const &
Returns
Type Description
RowStream

Read(Transaction, std::string, KeySet, std::vector< std::string >, std::initializer_list< internal::NonConstructible >)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Parameters
Name Description
transaction Transaction
table std::string
keys KeySet
columns std::vector< std::string >
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

PartitionRead(Transaction, std::string, KeySet, std::vector< std::string >, ReadOptions const &, PartitionOptions const &)

Creates a set of partitions that can be used to execute a read operation in parallel.

Parameters
Name Description
transaction Transaction
table std::string
keys KeySet
columns std::vector< std::string >
read_options ReadOptions const &
partition_options PartitionOptions const &
Returns
Type Description
StatusOr< std::vector< ReadPartition > >

PartitionRead(Transaction, std::string, KeySet, std::vector< std::string >, std::initializer_list< internal::NonConstructible >)

Creates a set of partitions that can be used to execute a read operation in parallel.

Parameters
Name Description
transaction Transaction
table std::string
keys KeySet
columns std::vector< std::string >
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< std::vector< ReadPartition > >

ExecuteQuery(SqlStatement, QueryOptions const &)

Executes a SQL query.

Parameters
Name Description
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
RowStream

ExecuteQuery(SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a SQL query.

Parameters
Name Description
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

ExecuteQuery(Transaction::SingleUseOptions, SqlStatement, QueryOptions const &)

Executes a SQL query.

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
RowStream

ExecuteQuery(Transaction::SingleUseOptions, SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a SQL query.

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

ExecuteQuery(Transaction, SqlStatement, QueryOptions const &)

Executes a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
RowStream

ExecuteQuery(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

ExecuteQuery(QueryPartition const &, QueryOptions const &)

Executes a SQL query on a subset of rows in a database.

Parameters
Name Description
partition QueryPartition const &
opts QueryOptions const &
Returns
Type Description
RowStream

ExecuteQuery(QueryPartition const &, std::initializer_list< internal::NonConstructible >)

Executes a SQL query on a subset of rows in a database.

Parameters
Name Description
partition QueryPartition const &
std::initializer_list< internal::NonConstructible >
Returns
Type Description
RowStream

ProfileQuery(SqlStatement, QueryOptions const &)

Profiles a SQL query.

Parameters
Name Description
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
ProfileQueryResult

ProfileQuery(SqlStatement, std::initializer_list< internal::NonConstructible >)

Profiles a SQL query.

Parameters
Name Description
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction::SingleUseOptions, SqlStatement, QueryOptions const &)

Profiles a SQL query.

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction::SingleUseOptions, SqlStatement, std::initializer_list< internal::NonConstructible >)

Profiles a SQL query.

Parameters
Name Description
transaction_options Transaction::SingleUseOptions
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction, SqlStatement, QueryOptions const &)

Profiles a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Profiles a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
ProfileQueryResult

ExecuteDml(Transaction, SqlStatement, QueryOptions const &)

Executes a SQL DML statement.

Parameters
Name Description
transaction Transaction
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
StatusOr< DmlResult >

ExecuteDml(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a SQL DML statement.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< DmlResult >

ProfileDml(Transaction, SqlStatement, QueryOptions const &)

Executes a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
StatusOr< ProfileDmlResult >

ProfileDml(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a SQL query.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< ProfileDmlResult >

AnalyzeSql(Transaction, SqlStatement, QueryOptions const &)

Analyzes the execution plan of a SQL statement.

Parameters
Name Description
transaction Transaction
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
StatusOr< ExecutionPlan >

AnalyzeSql(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Analyzes the execution plan of a SQL statement.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< ExecutionPlan >

ExecutePartitionedDml(SqlStatement, QueryOptions const &)

Executes a Partitioned DML SQL query.

Parameters
Name Description
statement SqlStatement
opts QueryOptions const &
Returns
Type Description
StatusOr< PartitionedDmlResult >

ExecutePartitionedDml(SqlStatement, std::initializer_list< internal::NonConstructible >)

Executes a Partitioned DML SQL query.

Parameters
Name Description
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< PartitionedDmlResult >

PartitionQuery(Transaction, SqlStatement, PartitionOptions const &)

Creates a set of partitions that can be used to execute a query operation in parallel.

Parameters
Name Description
transaction Transaction
statement SqlStatement
partition_options PartitionOptions const &
Returns
Type Description
StatusOr< std::vector< QueryPartition > >

PartitionQuery(Transaction, SqlStatement, std::initializer_list< internal::NonConstructible >)

Creates a set of partitions that can be used to execute a query operation in parallel.

Parameters
Name Description
transaction Transaction
statement SqlStatement
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< std::vector< QueryPartition > >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, std::unique_ptr< TransactionRerunPolicy >, std::unique_ptr< BackoffPolicy >, CommitOptions const &)

Commits a read-write transaction.

Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &
rerun_policy std::unique_ptr< TransactionRerunPolicy >
backoff_policy std::unique_ptr< BackoffPolicy >
commit_options CommitOptions const &
Returns
Type Description
StatusOr< CommitResult >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, std::unique_ptr< TransactionRerunPolicy >, std::unique_ptr< BackoffPolicy >, std::initializer_list< internal::NonConstructible >)

Commits a read-write transaction.

Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &
rerun_policy std::unique_ptr< TransactionRerunPolicy >
backoff_policy std::unique_ptr< BackoffPolicy >
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< CommitResult >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, CommitOptions const &)

Commits a read-write transaction.

Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &
commit_options CommitOptions const &
Returns
Type Description
StatusOr< CommitResult >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, std::initializer_list< internal::NonConstructible >)

Backwards compatibility for CommitOptions.

Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< CommitResult >

Commit(Mutations, CommitOptions const &)

Commits the mutations, using the options, atomically in order.

Parameters
Name Description
mutations Mutations
commit_options CommitOptions const &
Returns
Type Description
StatusOr< CommitResult >

Commit(Mutations, std::initializer_list< internal::NonConstructible >)

Commits the mutations, using the options, atomically in order.

Parameters
Name Description
mutations Mutations
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< CommitResult >

Commit(Transaction, Mutations, CommitOptions const &)

Commits a read-write transaction.

Parameters
Name Description
transaction Transaction
mutations Mutations
commit_options CommitOptions const &
Returns
Type Description
StatusOr< CommitResult >

Commit(Transaction, Mutations, std::initializer_list< internal::NonConstructible >)

Commits a read-write transaction.

Parameters
Name Description
transaction Transaction
mutations Mutations
std::initializer_list< internal::NonConstructible >
Returns
Type Description
StatusOr< CommitResult >

Read(std::string, KeySet, std::vector< std::string >, Options)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
void ReadData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  auto rows = client.Read("Albums", google::cloud::spanner::KeySet::All(),
                          {"SingerId", "AlbumId", "AlbumTitle"});
  using RowType = std::tuple<std::int64_t, std::int64_t, std::string>;
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "AlbumId: " << std::get<1>(*row) << "\t";
    std::cout << "AlbumTitle: " << std::get<2>(*row) << "\n";
  }

  std::cout << "Read completed for [spanner_read_data]\n";
}
Parameters
Name Description
table std::string

The name of the table in the database to be read.

keys KeySet

Identifies the rows to be yielded. If read_options.index_name is set, names keys in that index; otherwise names keys in the primary index of table. It is not an error for keys to name rows that do not exist in the database; Read yields nothing for nonexistent rows.

columns std::vector< std::string >

The columns of table to be returned for each row matching this request.

opts Options

Options used for this request.

Returns
Type Description
RowStream

Read(Transaction::SingleUseOptions, std::string, KeySet, std::vector< std::string >, Options)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
void ReadData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  auto rows = client.Read("Albums", google::cloud::spanner::KeySet::All(),
                          {"SingerId", "AlbumId", "AlbumTitle"});
  using RowType = std::tuple<std::int64_t, std::int64_t, std::string>;
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "AlbumId: " << std::get<1>(*row) << "\t";
    std::cout << "AlbumTitle: " << std::get<2>(*row) << "\n";
  }

  std::cout << "Read completed for [spanner_read_data]\n";
}
Parameters
Name Description
transaction_options Transaction::SingleUseOptions

Execute this read in a single-use transaction with these options.

table std::string

The name of the table in the database to be read.

keys KeySet

Identifies the rows to be yielded. If read_options.index_name is set, names keys in that index; otherwise names keys in the primary index of table. It is not an error for keys to name rows that do not exist in the database; Read yields nothing for nonexistent rows.

columns std::vector< std::string >

The columns of table to be returned for each row matching this request.

opts Options

Options used for this request.

Returns
Type Description
RowStream

Read(Transaction, std::string, KeySet, std::vector< std::string >, Options)

Reads rows from the database using key lookups and scans, as a simple key/value style alternative to ExecuteQuery().

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
void ReadData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  auto rows = client.Read("Albums", google::cloud::spanner::KeySet::All(),
                          {"SingerId", "AlbumId", "AlbumTitle"});
  using RowType = std::tuple<std::int64_t, std::int64_t, std::string>;
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "AlbumId: " << std::get<1>(*row) << "\t";
    std::cout << "AlbumTitle: " << std::get<2>(*row) << "\n";
  }

  std::cout << "Read completed for [spanner_read_data]\n";
}
Parameters
Name Description
transaction Transaction

Execute this read as part of an existing transaction.

table std::string

The name of the table in the database to be read.

keys KeySet

Identifies the rows to be yielded. If read_options.index_name is set, names keys in that index; otherwise names keys in the primary index of table. It is not an error for keys to name rows that do not exist in the database; Read yields nothing for nonexistent rows.

columns std::vector< std::string >

The columns of table to be returned for each row matching this request.

opts Options

Options used for this request.

Returns
Type Description
RowStream

Read(ReadPartition const &, Options)

Reads rows from a subset of rows in a database.

Requires a prior call to PartitionRead to obtain the partition information; see the documentation of that method for full details.

Example
  google::cloud::StatusOr<spanner::ReadPartition> partition =
      remote_connection.ReceiveReadPartitionFromRemoteMachine();
  if (!partition) throw std::move(partition).status();
  for (auto& row : client.Read(*partition)) {
    if (row.status().code() ==                           
        google::cloud::StatusCode::kPermissionDenied) {  
      continue;                                          
    }                                                    
    if (!row) throw std::move(row).status();
    ProcessRow(*row);
  }
Parameters
Name Description
partition ReadPartition const &

A ReadPartition, obtained by calling PartitionRead.

opts Options

Options used for this request.

Returns
Type Description
RowStream

PartitionRead(Transaction, std::string, KeySet, std::vector< std::string >, Options)

Creates a set of partitions that can be used to execute a read operation in parallel.

Each of the returned partitions can be passed to Read to specify a subset of the read result to read.

There are no ordering guarantees on rows returned among the returned partition, or even within each individual Read call issued with a given partition.

Partitions become invalid when the session used to create them is deleted, is idle for too long, begins a new transaction, or becomes too old. When any of these happen, it is not possible to resume the read, and the whole operation must be restarted from the beginning.

Example
  spanner::Transaction ro_transaction = spanner::MakeReadOnlyTransaction();
  google::cloud::StatusOr<std::vector<spanner::ReadPartition>> partitions =
      client.PartitionRead(
          ro_transaction, "Singers", key_set,
          {"SingerId", "FirstName", "LastName"},
          google::cloud::Options{}.set<spanner::PartitionDataBoostOption>(
              true));
  if (!partitions) throw std::move(partitions).status();
  for (auto& partition : *partitions) {
    remote_connection.SendPartitionToRemoteMachine(partition);
  }
Parameters
Name Description
transaction Transaction

The transaction to execute the operation in. Must be a read-only snapshot transaction.

table std::string

The name of the table in the database to be read.

keys KeySet

Identifies the rows to be yielded. If read_options.index_name is set, names keys in that index; otherwise names keys in the primary index of table. It is not an error for keys to name rows that do not exist in the database; Read yields nothing for nonexistent rows.

columns std::vector< std::string >

The columns of table to be returned for each row matching this request.

opts Options

Options used for this request.

Returns
Type Description
StatusOr< std::vector< ReadPartition > >

A StatusOr containing a vector of ReadPartition or error status on failure.

ExecuteQuery(SqlStatement, Options)

Executes a SQL query.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

SELECT * ... queries are supported, but there's no guarantee about the order, nor number, of returned columns. Therefore, the caller must look up the wanted values in each row by column name. When the desired column names are known in advance, it is better to list them explicitly in the query's SELECT statement, so that unnecessary values are not returned/ignored, and the column order is known. This enables more efficient and simpler code.

Can also execute a DML statement with a returning clause in a read/write transaction.

Example

Query with explicitly selected columns.

void QueryData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  spanner::SqlStatement select("SELECT SingerId, LastName FROM Singers");
  using RowType = std::tuple<std::int64_t, std::string>;
  auto rows = client.ExecuteQuery(std::move(select));
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "LastName: " << std::get<1>(*row) << "\n";
  }

  std::cout << "Query completed for [spanner_query_data]\n";
}
Example

Using SELECT *.

void QueryDataSelectStar(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  // With a "SELECT *" query, we don't know the order in which the columns will
  // be returned (nor the number of columns). Therefore, we look up each value
  // based on the column name rather than its position.
  spanner::SqlStatement select_star("SELECT * FROM Singers");
  for (auto& row : client.ExecuteQuery(std::move(select_star))) {
    if (!row) throw std::move(row).status();

    if (auto singer_id = row->get<std::int64_t>("SingerId")) {
      std::cout << "SingerId: " << *singer_id << "\t";
    } else {
      std::cerr << singer_id.status();
    }

    if (auto last_name = row->get<std::string>("LastName")) {
      std::cout << "LastName: " << *last_name;
    } else {
      std::cerr << last_name.status();
    }
    std::cout << "\n";
  }
  std::cout << "Query completed for [spanner_query_data_select_star]\n";
}
Example

Using a DML statement with THEN RETURN.

void UpdateUsingDmlReturning(google::cloud::spanner::Client client) {
  // Update MarketingBudget column for records satisfying a particular
  // condition and return the modified MarketingBudget column of the
  // updated records using `THEN RETURN MarketingBudget`.
  auto commit = client.Commit(
      [&client](google::cloud::spanner::Transaction txn)
          -> google::cloud::StatusOr<google::cloud::spanner::Mutations> {
        auto sql = google::cloud::spanner::SqlStatement(R"""(
            UPDATE Albums SET MarketingBudget = MarketingBudget * 2
              WHERE SingerId = 1 AND AlbumId = 1
              THEN RETURN MarketingBudget
        )""");
        using RowType = std::tuple<absl::optional<std::int64_t>>;
        auto rows = client.ExecuteQuery(std::move(txn), std::move(sql));
        // Note: This mutator might be re-run, or its effects discarded, so
        // changing non-transactional state (e.g., by producing output) is,
        // in general, not something to be imitated.
        for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) {
          if (!row) return std::move(row).status();
          std::cout << "MarketingBudget: ";
          if (std::get<0>(*row).has_value()) {
            std::cout << *std::get<0>(*row);
          } else {
            std::cout << "NULL";
          }
          std::cout << "\n";
        }
        std::cout << "Updated row(s) count: " << rows.RowsModified() << "\n";
        return google::cloud::spanner::Mutations{};
      });
  if (!commit) throw std::move(commit).status();
}
Parameters
Name Description
statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
RowStream

ExecuteQuery(Transaction::SingleUseOptions, SqlStatement, Options)

Executes a SQL query.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

SELECT * ... queries are supported, but there's no guarantee about the order, nor number, of returned columns. Therefore, the caller must look up the wanted values in each row by column name. When the desired column names are known in advance, it is better to list them explicitly in the query's SELECT statement, so that unnecessary values are not returned/ignored, and the column order is known. This enables more efficient and simpler code.

Can also execute a DML statement with a returning clause in a read/write transaction.

Example

Query with explicitly selected columns.

void QueryData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  spanner::SqlStatement select("SELECT SingerId, LastName FROM Singers");
  using RowType = std::tuple<std::int64_t, std::string>;
  auto rows = client.ExecuteQuery(std::move(select));
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "LastName: " << std::get<1>(*row) << "\n";
  }

  std::cout << "Query completed for [spanner_query_data]\n";
}
Example

Using SELECT *.

void QueryDataSelectStar(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  // With a "SELECT *" query, we don't know the order in which the columns will
  // be returned (nor the number of columns). Therefore, we look up each value
  // based on the column name rather than its position.
  spanner::SqlStatement select_star("SELECT * FROM Singers");
  for (auto& row : client.ExecuteQuery(std::move(select_star))) {
    if (!row) throw std::move(row).status();

    if (auto singer_id = row->get<std::int64_t>("SingerId")) {
      std::cout << "SingerId: " << *singer_id << "\t";
    } else {
      std::cerr << singer_id.status();
    }

    if (auto last_name = row->get<std::string>("LastName")) {
      std::cout << "LastName: " << *last_name;
    } else {
      std::cerr << last_name.status();
    }
    std::cout << "\n";
  }
  std::cout << "Query completed for [spanner_query_data_select_star]\n";
}
Example

Using a DML statement with THEN RETURN.

void UpdateUsingDmlReturning(google::cloud::spanner::Client client) {
  // Update MarketingBudget column for records satisfying a particular
  // condition and return the modified MarketingBudget column of the
  // updated records using `THEN RETURN MarketingBudget`.
  auto commit = client.Commit(
      [&client](google::cloud::spanner::Transaction txn)
          -> google::cloud::StatusOr<google::cloud::spanner::Mutations> {
        auto sql = google::cloud::spanner::SqlStatement(R"""(
            UPDATE Albums SET MarketingBudget = MarketingBudget * 2
              WHERE SingerId = 1 AND AlbumId = 1
              THEN RETURN MarketingBudget
        )""");
        using RowType = std::tuple<absl::optional<std::int64_t>>;
        auto rows = client.ExecuteQuery(std::move(txn), std::move(sql));
        // Note: This mutator might be re-run, or its effects discarded, so
        // changing non-transactional state (e.g., by producing output) is,
        // in general, not something to be imitated.
        for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) {
          if (!row) return std::move(row).status();
          std::cout << "MarketingBudget: ";
          if (std::get<0>(*row).has_value()) {
            std::cout << *std::get<0>(*row);
          } else {
            std::cout << "NULL";
          }
          std::cout << "\n";
        }
        std::cout << "Updated row(s) count: " << rows.RowsModified() << "\n";
        return google::cloud::spanner::Mutations{};
      });
  if (!commit) throw std::move(commit).status();
}
Parameters
Name Description
transaction_options Transaction::SingleUseOptions

Execute this query in a single-use transaction with these options.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
RowStream

ExecuteQuery(Transaction, SqlStatement, Options)

Executes a SQL query.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

SELECT * ... queries are supported, but there's no guarantee about the order, nor number, of returned columns. Therefore, the caller must look up the wanted values in each row by column name. When the desired column names are known in advance, it is better to list them explicitly in the query's SELECT statement, so that unnecessary values are not returned/ignored, and the column order is known. This enables more efficient and simpler code.

Can also execute a DML statement with a returning clause in a read/write transaction.

Example

Query with explicitly selected columns.

void QueryData(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  spanner::SqlStatement select("SELECT SingerId, LastName FROM Singers");
  using RowType = std::tuple<std::int64_t, std::string>;
  auto rows = client.ExecuteQuery(std::move(select));
  for (auto& row : spanner::StreamOf<RowType>(rows)) {
    if (!row) throw std::move(row).status();
    std::cout << "SingerId: " << std::get<0>(*row) << "\t";
    std::cout << "LastName: " << std::get<1>(*row) << "\n";
  }

  std::cout << "Query completed for [spanner_query_data]\n";
}
Example

Using SELECT *.

void QueryDataSelectStar(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;

  // With a "SELECT *" query, we don't know the order in which the columns will
  // be returned (nor the number of columns). Therefore, we look up each value
  // based on the column name rather than its position.
  spanner::SqlStatement select_star("SELECT * FROM Singers");
  for (auto& row : client.ExecuteQuery(std::move(select_star))) {
    if (!row) throw std::move(row).status();

    if (auto singer_id = row->get<std::int64_t>("SingerId")) {
      std::cout << "SingerId: " << *singer_id << "\t";
    } else {
      std::cerr << singer_id.status();
    }

    if (auto last_name = row->get<std::string>("LastName")) {
      std::cout << "LastName: " << *last_name;
    } else {
      std::cerr << last_name.status();
    }
    std::cout << "\n";
  }
  std::cout << "Query completed for [spanner_query_data_select_star]\n";
}
Example

Using a DML statement with THEN RETURN.

void UpdateUsingDmlReturning(google::cloud::spanner::Client client) {
  // Update MarketingBudget column for records satisfying a particular
  // condition and return the modified MarketingBudget column of the
  // updated records using `THEN RETURN MarketingBudget`.
  auto commit = client.Commit(
      [&client](google::cloud::spanner::Transaction txn)
          -> google::cloud::StatusOr<google::cloud::spanner::Mutations> {
        auto sql = google::cloud::spanner::SqlStatement(R"""(
            UPDATE Albums SET MarketingBudget = MarketingBudget * 2
              WHERE SingerId = 1 AND AlbumId = 1
              THEN RETURN MarketingBudget
        )""");
        using RowType = std::tuple<absl::optional<std::int64_t>>;
        auto rows = client.ExecuteQuery(std::move(txn), std::move(sql));
        // Note: This mutator might be re-run, or its effects discarded, so
        // changing non-transactional state (e.g., by producing output) is,
        // in general, not something to be imitated.
        for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) {
          if (!row) return std::move(row).status();
          std::cout << "MarketingBudget: ";
          if (std::get<0>(*row).has_value()) {
            std::cout << *std::get<0>(*row);
          } else {
            std::cout << "NULL";
          }
          std::cout << "\n";
        }
        std::cout << "Updated row(s) count: " << rows.RowsModified() << "\n";
        return google::cloud::spanner::Mutations{};
      });
  if (!commit) throw std::move(commit).status();
}
Parameters
Name Description
transaction Transaction

Execute this query as part of an existing transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
RowStream

ExecuteQuery(QueryPartition const &, Options)

Executes a SQL query on a subset of rows in a database.

Requires a prior call to PartitionQuery to obtain the partition information; see the documentation of that method for full details.

Example
  google::cloud::StatusOr<spanner::QueryPartition> partition =
      remote_connection.ReceiveQueryPartitionFromRemoteMachine();
  if (!partition) throw std::move(partition).status();
  for (auto& row : client.ExecuteQuery(*partition)) {
    if (row.status().code() ==                           
        google::cloud::StatusCode::kPermissionDenied) {  
      continue;                                          
    }                                                    
    if (!row) throw std::move(row).status();
    ProcessRow(*row);
  }
Parameters
Name Description
partition QueryPartition const &

A QueryPartition, obtained by calling PartitionQuery.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
RowStream

ProfileQuery(SqlStatement, Options)

Profiles a SQL query.

Profiling executes the query, provides the resulting rows, ExecutionPlan, and execution statistics.

Operations inside read-write transactions might return kAborted. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
  namespace spanner = ::google::cloud::spanner;
  spanner::SqlStatement select(
      "SELECT AlbumId, AlbumTitle, MarketingBudget"
      " FROM Albums"
      " WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'");
  auto profile_query_result = client.ProfileQuery(std::move(select));
  for (auto& row : profile_query_result) {
    if (!row) throw std::move(row).status();
    // Discard rows for brevity in this example.
  }

  // Stats are only available after all rows from the result have been read.
  auto execution_stats = profile_query_result.ExecutionStats();
  if (execution_stats) {
    for (auto const& stat : *execution_stats) {
      std::cout << stat.first << ":\t" << stat.second << "\n";
    }
  }
Parameters
Name Description
statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction::SingleUseOptions, SqlStatement, Options)

Profiles a SQL query.

Profiling executes the query, provides the resulting rows, ExecutionPlan, and execution statistics.

Operations inside read-write transactions might return kAborted. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
  namespace spanner = ::google::cloud::spanner;
  spanner::SqlStatement select(
      "SELECT AlbumId, AlbumTitle, MarketingBudget"
      " FROM Albums"
      " WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'");
  auto profile_query_result = client.ProfileQuery(std::move(select));
  for (auto& row : profile_query_result) {
    if (!row) throw std::move(row).status();
    // Discard rows for brevity in this example.
  }

  // Stats are only available after all rows from the result have been read.
  auto execution_stats = profile_query_result.ExecutionStats();
  if (execution_stats) {
    for (auto const& stat : *execution_stats) {
      std::cout << stat.first << ":\t" << stat.second << "\n";
    }
  }
Parameters
Name Description
transaction_options Transaction::SingleUseOptions

Execute this query in a single-use transaction with these options.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
ProfileQueryResult

ProfileQuery(Transaction, SqlStatement, Options)

Profiles a SQL query.

Profiling executes the query, provides the resulting rows, ExecutionPlan, and execution statistics.

Operations inside read-write transactions might return kAborted. If this occurs, the application should restart the transaction from the beginning.

Callers can optionally supply a Transaction or Transaction::SingleUseOptions used to create a single-use transaction - or neither, in which case a single-use transaction with default options is used.

Example
  namespace spanner = ::google::cloud::spanner;
  spanner::SqlStatement select(
      "SELECT AlbumId, AlbumTitle, MarketingBudget"
      " FROM Albums"
      " WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'");
  auto profile_query_result = client.ProfileQuery(std::move(select));
  for (auto& row : profile_query_result) {
    if (!row) throw std::move(row).status();
    // Discard rows for brevity in this example.
  }

  // Stats are only available after all rows from the result have been read.
  auto execution_stats = profile_query_result.ExecutionStats();
  if (execution_stats) {
    for (auto const& stat : *execution_stats) {
      std::cout << stat.first << ":\t" << stat.second << "\n";
    }
  }
Parameters
Name Description
transaction Transaction

Execute this query as part of an existing transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
ProfileQueryResult

PartitionQuery(Transaction, SqlStatement, Options)

Creates a set of partitions that can be used to execute a query operation in parallel.

Each of the returned partitions can be passed to ExecuteQuery to specify a subset of the query result to read.

Partitions become invalid when the session used to create them is deleted, is idle for too long, begins a new transaction, or becomes too old. When any of these happen, it is not possible to resume the query, and the whole operation must be restarted from the beginning.

Example
  google::cloud::StatusOr<std::vector<spanner::QueryPartition>> partitions =
      client.PartitionQuery(
          spanner::MakeReadOnlyTransaction(),
          spanner::SqlStatement(
              "SELECT SingerId, FirstName, LastName FROM Singers"),
          google::cloud::Options{}.set<spanner::PartitionDataBoostOption>(
              true));
  if (!partitions) throw std::move(partitions).status();
  for (auto& partition : *partitions) {
    remote_connection.SendPartitionToRemoteMachine(partition);
  }
Parameters
Name Description
transaction Transaction

The transaction to execute the operation in. Must be a read-only snapshot transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

Options used for this request.

Returns
Type Description
StatusOr< std::vector< QueryPartition > >

A StatusOr containing a vector of QueryPartitions or error status on failure.

ExecuteDml(Transaction, SqlStatement, Options)

Executes a SQL DML statement.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Example
  using ::google::cloud::StatusOr;
  namespace spanner = ::google::cloud::spanner;
  std::int64_t rows_inserted;
  auto commit_result = client.Commit(
      [&client, &rows_inserted](
          spanner::Transaction txn) -> StatusOr<spanner::Mutations> {
        auto insert = client.ExecuteDml(
            std::move(txn),
            spanner::SqlStatement(
                "INSERT INTO Singers (SingerId, FirstName, LastName)"
                "  VALUES (10, 'Virginia', 'Watson')"));
        if (!insert) return std::move(insert).status();
        rows_inserted = insert->RowsModified();
        return spanner::Mutations{};
      });
  if (!commit_result) throw std::move(commit_result).status();
  std::cout << "Rows inserted: " << rows_inserted;
Parameters
Name Description
transaction Transaction

Execute this query as part of an existing transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
StatusOr< DmlResult >

ProfileDml(Transaction, SqlStatement, Options)

Profiles a SQL DML statement.

Profiling executes the DML statement, provides the modified row count, ExecutionPlan, and execution statistics.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Example
  spanner::ProfileDmlResult dml_result;
  auto commit_result = client.Commit(
      [&client,
       &dml_result](spanner::Transaction txn) -> StatusOr<spanner::Mutations> {
        auto update = client.ProfileDml(
            std::move(txn),
            spanner::SqlStatement(
                "UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
                "  WHERE SingerId = 1 AND AlbumId = 1"));
        if (!update) return std::move(update).status();
        dml_result = *std::move(update);
        return spanner::Mutations{};
      });
  if (!commit_result) throw std::move(commit_result).status();

  // Stats only available after statement has been executed.
  std::cout << "Rows modified: " << dml_result.RowsModified();
  auto execution_stats = dml_result.ExecutionStats();
  if (execution_stats) {
    for (auto const& stat : *execution_stats) {
      std::cout << stat.first << ":\t" << stat.second << "\n";
    }
  }
Parameters
Name Description
transaction Transaction

Execute this query as part of an existing transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
StatusOr< ProfileDmlResult >

AnalyzeSql(Transaction, SqlStatement, Options)

Analyzes the execution plan of a SQL statement.

Analyzing provides the ExecutionPlan, but does not execute the SQL statement.

Operations inside read-write transactions might return ABORTED. If this occurs, the application should restart the transaction from the beginning.

Example
  // Only SQL queries with a Distributed Union as the first operator in the
  // `ExecutionPlan` can be partitioned.
  auto is_partitionable = [](spanner::ExecutionPlan const& plan) {
    return (!plan.plan_nodes().empty() &&
            plan.plan_nodes(0).kind() ==
                google::spanner::v1::PlanNode::RELATIONAL &&
            plan.plan_nodes(0).display_name() == "Distributed Union");
  };

  google::cloud::StatusOr<spanner::ExecutionPlan> plan = client.AnalyzeSql(
      spanner::MakeReadOnlyTransaction(),
      spanner::SqlStatement(
          "SELECT SingerId, FirstName, LastName FROM Singers"));
  if (!plan) throw std::move(plan).status();
  if (!is_partitionable(*plan)) {
    throw std::runtime_error("Query is not partitionable");
  }
Parameters
Name Description
transaction Transaction

Execute this query as part of an existing transaction.

statement SqlStatement

The SQL statement to execute.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
StatusOr< ExecutionPlan >

ExecuteBatchDml(Transaction, std::vector< SqlStatement >, Options)

Executes a batch of SQL DML statements.

This method allows many statements to be run with lower latency than submitting them sequentially with ExecuteDml.

Statements are executed in order, sequentially. Execution will stop at the first failed statement; the remaining statements will not run.

As with all read-write transactions, the results will not be visible outside of the transaction until it is committed. For that reason, it is advisable to run this method from a Commit mutator.

Example
void DmlStructs(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;
  std::int64_t rows_modified = 0;
  auto commit_result =
      client.Commit([&client, &rows_modified](spanner::Transaction const& txn)
                        -> google::cloud::StatusOr<spanner::Mutations> {
        auto singer_info = std::make_tuple("Marc", "Richards");
        auto sql = spanner::SqlStatement(
            "UPDATE Singers SET FirstName = 'Keith' WHERE "
            "STRUCT<FirstName String, LastName String>(FirstName, LastName) "
            "= @name",
            {{"name", spanner::Value(std::move(singer_info))}});
        auto dml_result = client.ExecuteDml(txn, std::move(sql));
        if (!dml_result) return std::move(dml_result).status();
        rows_modified = dml_result->RowsModified();
        return spanner::Mutations{};
      });
  if (!commit_result) throw std::move(commit_result).status();
  std::cout << rows_modified
            << " update was successful [spanner_dml_structs]\n";
}
Parameters
Name Description
transaction Transaction

The read-write transaction to execute the operation in.

statements std::vector< SqlStatement >

The list of statements to execute in this batch. Statements are executed serially, such that the effects of statement i are visible to statement i+1. Each statement must be a DML statement. Execution will stop at the first failed statement; the remaining statements will not run. Must not be empty.

opts Options

(optional) The options to use for this call. Expected options are any of the types in the following option lists.

  • google::cloud::RequestOptionList
Returns
Type Description
StatusOr< BatchDmlResult >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, std::unique_ptr< TransactionRerunPolicy >, std::unique_ptr< BackoffPolicy >, Options)

Commits a read-write transaction.

Calls the mutator in the context of a new read-write transaction. The mutator can execute read/write operations using the transaction, and returns any additional Mutations to commit.

If the mutator succeeds and the transaction commits, then Commit() returns the CommitResult.

If the mutator returns a non-rerunnable status (according to the rerun_policy), the transaction is rolled back and that status is returned. Similarly, if the transaction fails to commit with a non- rerunnable status, that status is returned.

Otherwise the whole process repeats (subject to rerun_policy and backoff_policy), by building a new transaction and re-running the mutator. The lock priority of the operation increases after each rerun, meaning that the next attempt has a slightly better chance of success.

Note that the mutator should only return a rerunnable status when the transaction is no longer usable (e.g., it was aborted). Otherwise the transaction will be leaked.

Example
void CommitWithPolicies(google::cloud::spanner::Client client) {
  using ::google::cloud::StatusOr;
  namespace spanner = ::google::cloud::spanner;
  auto commit = client.Commit(
      [&client](spanner::Transaction txn) -> StatusOr<spanner::Mutations> {
        auto update = client.ExecuteDml(
            std::move(txn),
            spanner::SqlStatement(
                "UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
                "  WHERE SingerId = 1 AND AlbumId = 1"));
        if (!update) return std::move(update).status();
        return spanner::Mutations{};
      },
      // Retry for up to 42 minutes.
      spanner::LimitedTimeTransactionRerunPolicy(std::chrono::minutes(42))
          .clone(),
      // After a failure backoff for 2 seconds (with jitter), then triple the
      // backoff time on each retry, up to 5 minutes.
      spanner::ExponentialBackoffPolicy(std::chrono::seconds(2),
                                        std::chrono::minutes(5), 3.0)
          .clone());
  if (!commit) throw std::move(commit).status();
  std::cout << "commit-with-policies was successful\n";
}
Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &

the function called to create mutations

rerun_policy std::unique_ptr< TransactionRerunPolicy >

controls for how long (or how many times) the mutator will be rerun after the transaction aborts.

backoff_policy std::unique_ptr< BackoffPolicy >

controls how long Commit waits between reruns.

opts Options

(optional) The options to use for this call. Expected options include any of the following types:

Exceptions
Type Description
Rethrows any exception thrown by ``mutator`` (after rolling back the transaction). However, a [`RuntimeStatusError`](xref:classgoogle_1_1cloud_1_1RuntimeStatusError) exception is instead consumed and converted into a `mutator` return value of the enclosed [`Status`](xref:classgoogle_1_1cloud_1_1Status).
Returns
Type Description
StatusOr< CommitResult >

Commit(std::function< StatusOr< Mutations >(Transaction)> const &, Options)

Commits a read-write transaction.

Same as above, but uses the default rerun and backoff policies.

Example
  using ::google::cloud::StatusOr;
  namespace spanner = ::google::cloud::spanner;
  auto commit_result = client.Commit(
      [&client](spanner::Transaction txn) -> StatusOr<spanner::Mutations> {
        auto update = client.ExecuteDml(
            std::move(txn),
            spanner::SqlStatement(
                "UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
                "  WHERE SingerId = 1 AND AlbumId = 1"));
        if (!update) return std::move(update).status();
        return spanner::Mutations{};
      });
  if (!commit_result) throw std::move(commit_result).status();
Parameters
Name Description
mutator std::function< StatusOr< Mutations >(Transaction)> const &

the function called to create mutations

opts Options

(optional) The options to use for this call.

Returns
Type Description
StatusOr< CommitResult >

Commit(Mutations, Options)

Commits the mutations, using the options, atomically in order.

Example
  namespace spanner = ::google::cloud::spanner;
  auto commit_result = client.Commit(spanner::Mutations{
      spanner::UpdateMutationBuilder("Albums",
                                     {"SingerId", "AlbumId", "MarketingBudget"})
          .EmplaceRow(1, 1, 100000)
          .EmplaceRow(2, 2, 500000)
          .Build()});
  if (!commit_result) throw std::move(commit_result).status();

This function uses the re-run loop described above with the default policies.

Parameters
Name Description
mutations Mutations
opts Options
Returns
Type Description
StatusOr< CommitResult >

Commit(Transaction, Mutations, Options)

Commits a read-write transaction.

The commit might return a kAborted error. This can occur at any time. Commonly the cause is conflicts with concurrent transactions, however it can also happen for a variety of other reasons. If Commit returns kAborted, the caller may try to reapply the mutations within a new read-write transaction (which should share lock priority with the aborted transaction so that the new attempt has a slightly better chance of success).

Parameters
Name Description
transaction Transaction

The transaction to commit.

mutations Mutations

The mutations to be executed when this transaction commits. All mutations are applied atomically, in the order they appear in this list.

opts Options

(optional) The options to use for this call.

Returns
Type Description
StatusOr< CommitResult >

A StatusOr containing the result of the commit or error status on failure.

CommitAtLeastOnce(Transaction::ReadWriteOptions, Mutations, Options)

Commits a write transaction with at-least-once semantics.

Apply the given mutations atomically, using a single RPC, and therefore without replay protection. That is, it is possible that the mutations will be applied more than once. If the mutations are not idempotent, this may lead to a failure (for example, an insert may fail with "already exists" even though the row did not exist before the call was made). Accordingly, this call may only be appropriate for idempotent, latency- sensitive and/or high-throughput blind writing.

Example
  namespace spanner = ::google::cloud::spanner;

  // Delete the album with key (2,2) without automatic re-run (e.g., if the
  // transaction was aborted) or replay protection, but using a single RPC.
  auto commit_result = client.CommitAtLeastOnce(
      spanner::Transaction::ReadWriteOptions(),
      spanner::Mutations{
          spanner::DeleteMutationBuilder(
              "Albums", spanner::KeySet().AddKey(spanner::MakeKey(2, 2)))
              .Build()});

  if (commit_result) {
    std::cout << "Delete was successful\n";
  } else if (commit_result.status().code() ==
             google::cloud::StatusCode::kNotFound) {
    std::cout << "Delete was successful but seemingly replayed\n";
  } else if (commit_result.status().code() ==
             google::cloud::StatusCode::kAborted) {
    std::cout << "Delete was aborted\n";
  } else {
    throw std::move(commit_result).status();
  }
Parameters
Name Description
transaction_options Transaction::ReadWriteOptions

Execute the commit in a temporary transaction with these options.

mutations Mutations

The mutations to be executed when this transaction commits. All mutations are applied atomically, in the order they appear in this list.

opts Options

(optional) The options to use for this call.

Returns
Type Description
StatusOr< CommitResult >

A StatusOr containing the result of the commit or error status on failure.

Rollback(Transaction, Options)

Rolls back a read-write transaction, releasing any locks it holds.

At any time before Commit, the client can call Rollback to abort the transaction. It is a good idea to call this for any read-write transaction that includes one or more Read, ExecuteQuery, or ExecuteDml requests and ultimately decides not to commit.

Parameters
Name Description
transaction Transaction

The transaction to roll back.

opts Options

(optional) The options to use for this call.

Returns
Type Description
Status

The error status of the rollback.

ExecutePartitionedDml(SqlStatement, Options)

Executes a Partitioned DML SQL query.

Example
void DmlPartitionedDelete(google::cloud::spanner::Client client) {
  namespace spanner = ::google::cloud::spanner;
  auto result = client.ExecutePartitionedDml(
      spanner::SqlStatement("DELETE FROM Singers WHERE SingerId > 10"));
  if (!result) throw std::move(result).status();
  std::cout << "Deleted at least " << result->row_count_lower_bound
            << " row(s) [spanner_dml_partitioned_delete]\n";
}
See Also

Partitioned DML Transactions for an overview of Partitioned DML transactions.

See Also

Partitioned DML for a description of which SQL statements are supported in Partitioned DML transactions.

Parameters
Name Description
statement SqlStatement

the SQL statement to execute. Please see the spanner documentation for the restrictions on the SQL statements supported by this function.

opts Options

(optional) The Options to use for this call. If given, these will take precedence over the options set at the client and environment levels.

Returns
Type Description
StatusOr< PartitionedDmlResult >