Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions google/cloud/spanner/doc/spanner-main.dox
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ into your project.
- @ref spanner-auth-example
- @ref spanner-universe-domain-example
- @ref spanner-mocking
- @ref spanner-isolation-level-example
- The [Setting up your development environment] guide describes how to set up
a C++ development environment in various platforms, including the Google Cloud
C++ client libraries.
Expand Down Expand Up @@ -65,6 +66,19 @@ Follow these links to find examples for other `*Client` classes:

*/

/**
@page spanner-isolation-level-example Support Isolation Level

Cloud Spanner supports different isolation levels for read-write transactions.
You can specify a default isolation level at the client-level, or override it
at the transaction-level.

The following example shows how to set the isolation level:

@snippet samples.cc spanner-isolation-level-setting-sample

*/

/**
@page spanner-auth-example Override the authentication configuration

Expand Down
70 changes: 70 additions & 0 deletions google/cloud/spanner/samples/samples.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "google/cloud/spanner/backoff_policy.h"
#include "google/cloud/spanner/backup.h"
#include "google/cloud/spanner/create_instance_request_builder.h"
#include "google/cloud/spanner/options.h"
#include "google/cloud/spanner/row.h"
#include "google/cloud/spanner/testing/debug_log.h" // TODO(#4758): remove
#include "google/cloud/spanner/testing/instance_location.h"
Expand Down Expand Up @@ -3472,6 +3473,71 @@ void ReadWriteTransaction(google::cloud::spanner::Client client) {
}
//! [END spanner_read_write_transaction]

//! [START spanner_isolation_level] [spanner-isolation-level-setting-sample]
void IsolationLevelSetting(std::string const& project_id,
std::string const& instance_id,
std::string const& database_id) {
namespace spanner = ::google::cloud::spanner;
using ::google::cloud::Options;
using ::google::cloud::StatusOr;

auto db = spanner::Database(project_id, instance_id, database_id);

// The isolation level specified at the client-level will be applied
// to all RW transactions.
auto options = Options{}.set<spanner::TransactionIsolationLevelOption>(
spanner::Transaction::IsolationLevel::kSerializable);
auto client = spanner::Client(spanner::MakeConnection(db, options));

auto commit = client.Commit(
[&client](
spanner::Transaction const& txn) -> StatusOr<spanner::Mutations> {
// Read an AlbumTitle.
auto sql = spanner::SqlStatement(
"SELECT AlbumTitle from Albums WHERE SingerId = @SingerId and "
"AlbumId = @AlbumId",
{{"SingerId", spanner::Value(1)}, {"AlbumId", spanner::Value(1)}});
auto rows = client.ExecuteQuery(txn, std::move(sql));
for (auto const& row :
spanner::StreamOf<std::tuple<std::string>>(rows)) {
if (!row) return row.status();
std::cout << "Current album title: " << std::get<0>(*row) << "\n";
}

// Update the title.
auto update_sql = spanner::SqlStatement(
"UPDATE Albums "
"SET AlbumTitle = @AlbumTitle "
"WHERE SingerId = @SingerId and AlbumId = @AlbumId",
{{"AlbumTitle", spanner::Value("New Album Title")},
{"SingerId", spanner::Value(1)},
{"AlbumId", spanner::Value(1)}});
auto result = client.ExecuteDml(txn, std::move(update_sql));
if (!result) return result.status();
std::cout << result->RowsModified() << " record updated.\n";

return spanner::Mutations{};
},
// The isolation level specified at the transaction-level takes
// precedence over the isolation level configured at the client-level.
// kRepeatableRead is used here to demonstrate overriding the client-level
// setting.
Options{}.set<spanner::TransactionIsolationLevelOption>(
spanner::Transaction::IsolationLevel::kRepeatableRead));

if (!commit) throw std::move(commit).status();
std::cout << "Update was successful [spanner_isolation_level_setting]\n";
}
//! [END spanner_isolation_level] [spanner-isolation-level-setting-sample],

void IsolationLevelSettingCommand(std::vector<std::string> argv) {
if (argv.size() != 3) {
throw std::runtime_error(
"isolation-level-setting <project-id> <instance-id> <database-id>");
}
IsolationLevelSetting(argv[0], argv[1], argv[2]);
}

//! [START spanner_get_commit_stats]
void GetCommitStatistics(google::cloud::spanner::Client client) {
namespace spanner = ::google::cloud::spanner;
Expand Down Expand Up @@ -5190,6 +5256,7 @@ int RunOneCommand(std::vector<std::string> argv) {
make_command_entry("read-data-with-storing-index",
ReadDataWithStoringIndex),
make_command_entry("read-write-transaction", ReadWriteTransaction),
{"isolation-level-setting", IsolationLevelSettingCommand},
make_command_entry("get-commit-stats", GetCommitStatistics),
make_command_entry("dml-standard-insert", DmlStandardInsert),
make_command_entry("dml-standard-update", DmlStandardUpdate),
Expand Down Expand Up @@ -5888,6 +5955,9 @@ void RunAll(bool emulator) {
SampleBanner("spanner_directed_read");
DirectedRead(project_id, instance_id, database_id);

SampleBanner("isolation-level-setting");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument to SampleBanner() should be the sample tag, which, according to the START/END annotations you added, would be "spanner_isolation_level".

IsolationLevelSetting(project_id, instance_id, database_id);

SampleBanner("spanner_batch_client");
UsePartitionQuery(client);

Expand Down