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:
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";
}