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
11 changes: 11 additions & 0 deletions google-cloud-spanner/acceptance/spanner/client/crud_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,5 +251,16 @@
_(results.rows.count).must_equal 1
_(results.timestamp).wont_be :nil?
end

it "commits with read_lock_mode PESSIMISTIC for #{dialect}" do
timestamp = db[dialect].commit read_lock_mode: :PESSIMISTIC do |c|
c.insert "accounts", @default_rows[dialect][0]
end
_(timestamp).wont_be :nil?

results = db[dialect].read "accounts", ["account_id"], single_use: { timestamp: timestamp }
_(results.rows.count).must_equal 1
_(results.timestamp).wont_be :nil?
end
end
end
101 changes: 85 additions & 16 deletions google-cloud-spanner/lib/google/cloud/spanner/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,13 @@ def read table, columns, keys: nil, index: nil, limit: nil,
# * `:retry_codes` (`Array<String>`) - The error codes that should
# trigger a retry.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
Expand Down Expand Up @@ -1161,7 +1168,7 @@ def read table, columns, keys: nil, index: nil, limit: nil,
def upsert table, rows,
exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil
call_options: nil, read_lock_mode: nil
request_options = Convert.to_request_options \
request_options, tag_type: :transaction_tag

Expand All @@ -1171,7 +1178,8 @@ def upsert table, rows,
isolation_level: isolation_level,
commit_options: commit_options,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
end
end
alias save upsert
Expand Down Expand Up @@ -1257,6 +1265,15 @@ def upsert table, rows,
# trigger a retry.
#
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
#
Expand Down Expand Up @@ -1312,7 +1329,7 @@ def upsert table, rows,
def insert table, rows,
exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil
call_options: nil, read_lock_mode: nil
request_options = Convert.to_request_options \
request_options, tag_type: :transaction_tag

Expand All @@ -1322,7 +1339,8 @@ def insert table, rows,
isolation_level: isolation_level,
commit_options: commit_options,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
end
end

Expand Down Expand Up @@ -1406,6 +1424,14 @@ def insert table, rows,
# * `:retry_codes` (`Array<String>`) - The error codes that should
# trigger a retry.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
Expand Down Expand Up @@ -1461,7 +1487,7 @@ def insert table, rows,
def update table, rows,
exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil
call_options: nil, read_lock_mode: nil
request_options = Convert.to_request_options \
request_options, tag_type: :transaction_tag

Expand All @@ -1471,7 +1497,8 @@ def update table, rows,
isolation_level: isolation_level,
commit_options: commit_options,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
end
end

Expand Down Expand Up @@ -1557,6 +1584,14 @@ def update table, rows,
# * `:retry_codes` (`Array<String>`) - The error codes that should
# trigger a retry.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
Expand Down Expand Up @@ -1612,14 +1647,15 @@ def update table, rows,
def replace table, rows,
exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil
call_options: nil, read_lock_mode: nil
@pool.with_session do |session|
session.replace table, rows,
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
isolation_level: isolation_level,
commit_options: commit_options,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
end
end

Expand Down Expand Up @@ -1684,6 +1720,15 @@ def replace table, rows,
# * `:retry_codes` (`Array<String>`) - The error codes that should
# trigger a retry.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
#
Expand Down Expand Up @@ -1732,7 +1777,7 @@ def replace table, rows,
def delete table, keys = [],
exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil
call_options: nil, read_lock_mode: nil
request_options = Convert.to_request_options \
request_options, tag_type: :transaction_tag

Expand All @@ -1742,7 +1787,8 @@ def delete table, keys = [],
isolation_level: isolation_level,
commit_options: commit_options,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
end
end

Expand Down Expand Up @@ -1805,6 +1851,15 @@ def delete table, keys = [],
# @yield [commit] The block for mutating the data.
# @yieldparam [Google::Cloud::Spanner::Commit] commit The Commit object.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @return [Time, CommitResponse] The timestamp at which the operation
# committed. If commit options are set it returns {CommitResponse}.
#
Expand Down Expand Up @@ -1863,7 +1918,7 @@ def delete table, keys = [],
#
def commit exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil, &block
call_options: nil, read_lock_mode: nil, &block
raise ArgumentError, "Must provide a block" unless block_given?

request_options = Convert.to_request_options \
Expand All @@ -1876,6 +1931,7 @@ def commit exclude_txn_from_change_streams: false,
commit_options: commit_options,
request_options: request_options,
call_options: call_options,
read_lock_mode: read_lock_mode,
&block
)
end
Expand Down Expand Up @@ -2042,6 +2098,15 @@ def batch_write exclude_txn_from_change_streams: false,
# * `:retry_codes` (`Array<String>`) - The error codes that should
# trigger a retry.
#
# @param [Google::Cloud::Spanner::V1::TransactionOptions::ReadWrite::ReadLockMode] read_lock_mode
# The read lock mode for the transaction.
# Can be one of the following:
# * `:READ_LOCK_MODE_UNSPECIFIED` : The default unspecified read lock mode.
# * `:PESSIMISTIC` : The pessimistic lock mode, where read locks are acquired immediately on read.
# * `:OPTIMISTIC` : The optimistic lock mode, where locks for reads are not acquired on read
# but instead on a commit to validate that the data has not changed since the transaction started.
#
#
# @yield [transaction] The block for reading and writing data.
# @yieldparam [Google::Cloud::Spanner::Transaction] transaction The
# Transaction object.
Expand Down Expand Up @@ -2144,7 +2209,7 @@ def batch_write exclude_txn_from_change_streams: false,
# end
#
def transaction deadline: 120, exclude_txn_from_change_streams: false,
commit_options: nil, request_options: nil, call_options: nil
commit_options: nil, request_options: nil, call_options: nil, read_lock_mode: nil
ensure_service!
unless Thread.current[IS_TRANSACTION_RUNNING_KEY].nil?
raise "Nested transactions are not allowed"
Expand All @@ -2158,7 +2223,8 @@ def transaction deadline: 120, exclude_txn_from_change_streams: false,
request_options, tag_type: :transaction_tag

@pool.with_session do |session|
tx = session.create_empty_transaction exclude_txn_from_change_streams: exclude_txn_from_change_streams
tx = session.create_empty_transaction \
exclude_txn_from_change_streams: exclude_txn_from_change_streams, read_lock_mode: read_lock_mode
if request_options
tx.transaction_tag = request_options[:transaction_tag]
end
Expand All @@ -2175,7 +2241,8 @@ def transaction deadline: 120, exclude_txn_from_change_streams: false,
tx.safe_begin_transaction!(
exclude_from_change_streams: exclude_txn_from_change_streams,
request_options: request_options,
call_options: call_options
call_options: call_options,
read_lock_mode: read_lock_mode
)
end

Expand All @@ -2195,7 +2262,8 @@ def transaction deadline: 120, exclude_txn_from_change_streams: false,
commit_options: commit_options,
request_options: request_options,
call_options: call_options,
precommit_token: tx.precommit_token
precommit_token: tx.precommit_token,
read_lock_mode: read_lock_mode
)

tx.precommit_token = commit_resp.precommit_token
Expand All @@ -2216,7 +2284,8 @@ def transaction deadline: 120, exclude_txn_from_change_streams: false,
previous_transaction_id = tx.transaction_id if tx.existing_transaction?
tx = session.create_empty_transaction(
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
previous_transaction_id: previous_transaction_id
previous_transaction_id: previous_transaction_id,
read_lock_mode: read_lock_mode
)
if request_options
tx.transaction_tag = request_options[:transaction_tag]
Expand Down
13 changes: 10 additions & 3 deletions google-cloud-spanner/lib/google/cloud/spanner/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,14 @@ def partition_query session_name, sql, transaction, params: nil,
def commit session_name, mutations = [],
transaction_id: nil, exclude_txn_from_change_streams: false,
isolation_level: nil, commit_options: nil, request_options: nil,
call_options: nil, precommit_token: nil
call_options: nil, precommit_token: nil, read_lock_mode: nil
route_to_leader = LARHeaders.commit
tx_opts = nil
if transaction_id.nil?
tx_opts = V1::TransactionOptions.new(
read_write: V1::TransactionOptions::ReadWrite.new,
read_write: V1::TransactionOptions::ReadWrite.new(
read_lock_mode: read_lock_mode
),
exclude_txn_from_change_streams: exclude_txn_from_change_streams,
isolation_level: isolation_level
)
Expand Down Expand Up @@ -640,7 +642,8 @@ def begin_transaction session_name,
call_options: nil,
route_to_leader: nil,
mutation_key: nil,
previous_transaction_id: nil
previous_transaction_id: nil,
read_lock_mode: nil
read_write = if previous_transaction_id.nil?
V1::TransactionOptions::ReadWrite.new
else
Expand All @@ -649,6 +652,10 @@ def begin_transaction session_name,
)
end

unless read_lock_mode.nil?
read_write.read_lock_mode = read_lock_mode
end

tx_opts = V1::TransactionOptions.new(
read_write: read_write,
exclude_txn_from_change_streams: exclude_txn_from_change_streams
Expand Down
Loading