Skip to content
Open
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
36 changes: 36 additions & 0 deletions spanner/spanner_isolation_level.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2026 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START spanner_isolation_level]
require "google/cloud/spanner"

def spanner_isolation_level project_id:, instance_id:, database_id:
# Instantiates a client with isolation_level: :SERIALIZABLE
spanner = Google::Cloud::Spanner.new project: project_id
client = spanner.client instance_id, database_id, isolation_level: :SERIALIZABLE

# Overrides isolation_level to :REPEATABLE_READ at transaction level
client.transaction isolation_level: :REPEATABLE_READ do |tx|
results = tx.execute_query "SELECT AlbumTitle FROM Albums WHERE SingerId = 1 AND AlbumId = 1"

results.rows.each do |row|
puts "AlbumTitle: #{row[:AlbumTitle]}"
end

row_count = tx.execute_update "UPDATE Albums SET AlbumTitle = 'A New Title' WHERE SingerId = 1 AND AlbumId = 1"

puts "#{row_count} records updated."
end
end
# [END spanner_isolation_level]
36 changes: 36 additions & 0 deletions spanner/spanner_read_lock_mode.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2026 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START spanner_read_lock_mode]
require "google/cloud/spanner"

def spanner_read_lock_mode project_id:, instance_id:, database_id:
# Instantiates a client with read_lock_mode: :OPTIMISTIC
spanner = Google::Cloud::Spanner.new project: project_id
client = spanner.client instance_id, database_id, read_lock_mode: :OPTIMISTIC

# Overrides read_lock_mode to :PESSIMISTIC at transaction level
client.transaction read_lock_mode: :PESSIMISTIC do |tx|
results = tx.execute_query "SELECT AlbumTitle FROM Albums WHERE SingerId = 2 AND AlbumId = 1"

results.rows.each do |row|
puts "AlbumTitle: #{row[:AlbumTitle]}"
end

row_count = tx.execute_update "UPDATE Albums SET AlbumTitle = 'A New Title' WHERE SingerId = 2 AND AlbumId = 1"

puts "#{row_count} records updated."
end
end
# [END spanner_read_lock_mode]
51 changes: 51 additions & 0 deletions spanner/spec/spanner_isolation_level_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2026 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require_relative "../spanner_isolation_level"
require "rspec"
require "google/cloud/spanner"

describe "Spanner Isolation Level Options" do
it "runs isolation level snippet successfully" do
if ENV["GOOGLE_CLOUD_SPANNER_TEST_INSTANCE"].nil? || ENV["GOOGLE_CLOUD_SPANNER_PROJECT"].nil?
skip "GOOGLE_CLOUD_SPANNER_TEST_INSTANCE and/or GOOGLE_CLOUD_SPANNER_PROJECT not defined"
end

@project_id = ENV["GOOGLE_CLOUD_SPANNER_PROJECT"]
@instance_id = ENV["GOOGLE_CLOUD_SPANNER_TEST_INSTANCE"]
@seed = SecureRandom.hex 8
@database_id = "test_db_#{@seed}"
@spanner = Google::Cloud::Spanner.new project: @project_id
@instance = @spanner.instance @instance_id

unless @instance.database @database_id
real_stdout = $stdout
$stdout = StringIO.new
create_database project_id: @project_id,
instance_id: @instance_id,
database_id: @database_id
$stdout = real_stdout
end

client = @spanner.client @instance_id, @database_id
client.insert "Singers", [{ SingerId: 1, FirstName: "Test" }]
client.insert "Albums", [{ SingerId: 1, AlbumId: 1, AlbumTitle: "Old Title" }]

expect {
spanner_isolation_level project_id: @project_id, instance_id: @instance_id, database_id: @database_id
}.to output(/AlbumTitle: Old Title\n1 records updated./).to_stdout

@instance.database(@database_id).drop
end
end
51 changes: 51 additions & 0 deletions spanner/spec/spanner_read_lock_mode_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2026 Google, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require_relative "../spanner_read_lock_mode"
require "rspec"
require "google/cloud/spanner"

describe "Spanner Read Lock Mode Options" do
it "runs read lock mode snippet successfully" do
if ENV["GOOGLE_CLOUD_SPANNER_TEST_INSTANCE"].nil? || ENV["GOOGLE_CLOUD_SPANNER_PROJECT"].nil?
skip "GOOGLE_CLOUD_SPANNER_TEST_INSTANCE and/or GOOGLE_CLOUD_SPANNER_PROJECT not defined"
end

@project_id = ENV["GOOGLE_CLOUD_SPANNER_PROJECT"]
@instance_id = ENV["GOOGLE_CLOUD_SPANNER_TEST_INSTANCE"]
@seed = SecureRandom.hex 8
@database_id = "test_db_#{@seed}"
@spanner = Google::Cloud::Spanner.new project: @project_id
@instance = @spanner.instance @instance_id

unless @instance.database @database_id
real_stdout = $stdout
$stdout = StringIO.new
create_database project_id: @project_id,
instance_id: @instance_id,
database_id: @database_id
$stdout = real_stdout
end

client = @spanner.client @instance_id, @database_id
client.insert "Singers", [{ SingerId: 2, FirstName: "Test" }]
client.insert "Albums", [{ SingerId: 2, AlbumId: 1, AlbumTitle: "Old Title" }]

expect {
spanner_read_lock_mode project_id: @project_id, instance_id: @instance_id, database_id: @database_id
}.to output(/AlbumTitle: Old Title\n1 records updated./).to_stdout

@instance.database(@database_id).drop
end
end