# Copyright 2018 Google LLC # # 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 # # https://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. module Google module Spanner module V1 # = Transactions # # Each session can have at most one active transaction at a time. After the # active transaction is completed, the session can immediately be # re-used for the next transaction. It is not necessary to create a # new session for each transaction. # # = Transaction Modes # # Cloud Spanner supports two transaction modes: # # 1. Locking read-write. This type of transaction is the only way # to write data into Cloud Spanner. These transactions rely on # pessimistic locking and, if necessary, two-phase commit. # Locking read-write transactions may abort, requiring the # application to retry. # # 2. Snapshot read-only. This transaction type provides guaranteed # consistency across several reads, but does not allow # writes. Snapshot read-only transactions can be configured to # read at timestamps in the past. Snapshot read-only # transactions do not need to be committed. # # For transactions that only read, snapshot read-only transactions # provide simpler semantics and are almost always faster. In # particular, read-only transactions do not take locks, so they do # not conflict with read-write transactions. As a consequence of not # taking locks, they also do not abort, so retry loops are not needed. # # Transactions may only read/write data in a single database. They # may, however, read/write data in different tables within that # database. # # == Locking Read-Write Transactions # # Locking transactions may be used to atomically read-modify-write # data anywhere in a database. This type of transaction is externally # consistent. # # Clients should attempt to minimize the amount of time a transaction # is active. Faster transactions commit with higher probability # and cause less contention. Cloud Spanner attempts to keep read locks # active as long as the transaction continues to do reads, and the # transaction has not been terminated by # {Google::Spanner::V1::Spanner::Commit Commit} or # {Google::Spanner::V1::Spanner::Rollback Rollback}. Long periods of # inactivity at the client may cause Cloud Spanner to release a # transaction's locks and abort it. # # Reads performed within a transaction acquire locks on the data # being read. Writes can only be done at commit time, after all reads # have been completed. # Conceptually, a read-write transaction consists of zero or more # reads or SQL queries followed by # {Google::Spanner::V1::Spanner::Commit Commit}. At any time before # {Google::Spanner::V1::Spanner::Commit Commit}, the client can send a # {Google::Spanner::V1::Spanner::Rollback Rollback} request to abort the # transaction. # # === Semantics # # Cloud Spanner can commit the transaction if all read locks it acquired # are still valid at commit time, and it is able to acquire write # locks for all writes. Cloud Spanner can abort the transaction for any # reason. If a commit attempt returns +ABORTED+, Cloud Spanner guarantees # that the transaction has not modified any user data in Cloud Spanner. # # Unless the transaction commits, Cloud Spanner makes no guarantees about # how long the transaction's locks were held for. It is an error to # use Cloud Spanner locks for any sort of mutual exclusion other than # between Cloud Spanner transactions themselves. # # === Retrying Aborted Transactions # # When a transaction aborts, the application can choose to retry the # whole transaction again. To maximize the chances of successfully # committing the retry, the client should execute the retry in the # same session as the original attempt. The original session's lock # priority increases with each consecutive abort, meaning that each # attempt has a slightly better chance of success than the previous. # # Under some circumstances (e.g., many transactions attempting to # modify the same row(s)), a transaction can abort many times in a # short period before successfully committing. Thus, it is not a good # idea to cap the number of retries a transaction can attempt; # instead, it is better to limit the total amount of wall time spent # retrying. # # === Idle Transactions # # A transaction is considered idle if it has no outstanding reads or # SQL queries and has not started a read or SQL query within the last 10 # seconds. Idle transactions can be aborted by Cloud Spanner so that they # don't hold on to locks indefinitely. In that case, the commit will # fail with error +ABORTED+. # # If this behavior is undesirable, periodically executing a simple # SQL query in the transaction (e.g., +SELECT 1+) prevents the # transaction from becoming idle. # # == Snapshot Read-Only Transactions # # Snapshot read-only transactions provides a simpler method than # locking read-write transactions for doing several consistent # reads. However, this type of transaction does not support writes. # # Snapshot transactions do not take locks. Instead, they work by # choosing a Cloud Spanner timestamp, then executing all reads at that # timestamp. Since they do not acquire locks, they do not block # concurrent read-write transactions. # # Unlike locking read-write transactions, snapshot read-only # transactions never abort. They can fail if the chosen read # timestamp is garbage collected; however, the default garbage # collection policy is generous enough that most applications do not # need to worry about this in practice. # # Snapshot read-only transactions do not need to call # {Google::Spanner::V1::Spanner::Commit Commit} or # {Google::Spanner::V1::Spanner::Rollback Rollback} (and in fact are not # permitted to do so). # # To execute a snapshot transaction, the client specifies a timestamp # bound, which tells Cloud Spanner how to choose a read timestamp. # # The types of timestamp bound are: # # * Strong (the default). # * Bounded staleness. # * Exact staleness. # # If the Cloud Spanner database to be read is geographically distributed, # stale read-only transactions can execute more quickly than strong # or read-write transaction, because they are able to execute far # from the leader replica. # # Each type of timestamp bound is discussed in detail below. # # === Strong # # Strong reads are guaranteed to see the effects of all transactions # that have committed before the start of the read. Furthermore, all # rows yielded by a single read are consistent with each other -- if # any part of the read observes a transaction, all parts of the read # see the transaction. # # Strong reads are not repeatable: two consecutive strong read-only # transactions might return inconsistent results if there are # concurrent writes. If consistency across reads is required, the # reads should be executed within a transaction or at an exact read # timestamp. # # See {Google::Spanner::V1::TransactionOptions::ReadOnly#strong TransactionOptions::ReadOnly#strong}. # # === Exact Staleness # # These timestamp bounds execute reads at a user-specified # timestamp. Reads at a timestamp are guaranteed to see a consistent # prefix of the global transaction history: they observe # modifications done by all transactions with a commit timestamp <= # the read timestamp, and observe none of the modifications done by # transactions with a larger commit timestamp. They will block until # all conflicting transactions that may be assigned commit timestamps # <= the read timestamp have finished. # # The timestamp can either be expressed as an absolute Cloud Spanner commit # timestamp or a staleness relative to the current time. # # These modes do not require a "negotiation phase" to pick a # timestamp. As a result, they execute slightly faster than the # equivalent boundedly stale concurrency modes. On the other hand, # boundedly stale reads usually return fresher results. # # See {Google::Spanner::V1::TransactionOptions::ReadOnly#read_timestamp TransactionOptions::ReadOnly#read_timestamp} and # {Google::Spanner::V1::TransactionOptions::ReadOnly#exact_staleness TransactionOptions::ReadOnly#exact_staleness}. # # === Bounded Staleness # # Bounded staleness modes allow Cloud Spanner to pick the read timestamp, # subject to a user-provided staleness bound. Cloud Spanner chooses the # newest timestamp within the staleness bound that allows execution # of the reads at the closest available replica without blocking. # # All rows yielded are consistent with each other -- if any part of # the read observes a transaction, all parts of the read see the # transaction. Boundedly stale reads are not repeatable: two stale # reads, even if they use the same staleness bound, can execute at # different timestamps and thus return inconsistent results. # # Boundedly stale reads execute in two phases: the first phase # negotiates a timestamp among all replicas needed to serve the # read. In the second phase, reads are executed at the negotiated # timestamp. # # As a result of the two phase execution, bounded staleness reads are # usually a little slower than comparable exact staleness # reads. However, they are typically able to return fresher # results, and are more likely to execute at the closest replica. # # Because the timestamp negotiation requires up-front knowledge of # which rows will be read, it can only be used with single-use # read-only transactions. # # See {Google::Spanner::V1::TransactionOptions::ReadOnly#max_staleness TransactionOptions::ReadOnly#max_staleness} and # {Google::Spanner::V1::TransactionOptions::ReadOnly#min_read_timestamp TransactionOptions::ReadOnly#min_read_timestamp}. # # === Old Read Timestamps and Garbage Collection # # Cloud Spanner continuously garbage collects deleted and overwritten data # in the background to reclaim storage space. This process is known # as "version GC". By default, version GC reclaims versions after they # are one hour old. Because of this, Cloud Spanner cannot perform reads # at read timestamps more than one hour in the past. This # restriction also applies to in-progress reads and/or SQL queries whose # timestamp become too old while executing. Reads and SQL queries with # too-old read timestamps fail with the error +FAILED_PRECONDITION+. # @!attribute [rw] read_write # @return [Google::Spanner::V1::TransactionOptions::ReadWrite] # Transaction may write. # # Authorization to begin a read-write transaction requires # +spanner.databases.beginOrRollbackReadWriteTransaction+ permission # on the +session+ resource. # @!attribute [rw] read_only # @return [Google::Spanner::V1::TransactionOptions::ReadOnly] # Transaction will not write. # # Authorization to begin a read-only transaction requires # +spanner.databases.beginReadOnlyTransaction+ permission # on the +session+ resource. class TransactionOptions # Message type to initiate a read-write transaction. Currently this # transaction type has no options. class ReadWrite; end # Message type to initiate a read-only transaction. # @!attribute [rw] strong # @return [true, false] # Read at a timestamp where all previously committed transactions # are visible. # @!attribute [rw] min_read_timestamp # @return [Google::Protobuf::Timestamp] # Executes all reads at a timestamp >= +min_read_timestamp+. # # This is useful for requesting fresher data than some previous # read, or data that is fresh enough to observe the effects of some # previously committed transaction whose timestamp is known. # # Note that this option can only be used in single-use transactions. # # A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds. # Example: +"2014-10-02T15:01:23.045123456Z"+. # @!attribute [rw] max_staleness # @return [Google::Protobuf::Duration] # Read data at a timestamp >= +NOW - max_staleness+ # seconds. Guarantees that all writes that have committed more # than the specified number of seconds ago are visible. Because # Cloud Spanner chooses the exact timestamp, this mode works even if # the client's local clock is substantially skewed from Cloud Spanner # commit timestamps. # # Useful for reading the freshest data available at a nearby # replica, while bounding the possible staleness if the local # replica has fallen behind. # # Note that this option can only be used in single-use # transactions. # @!attribute [rw] read_timestamp # @return [Google::Protobuf::Timestamp] # Executes all reads at the given timestamp. Unlike other modes, # reads at a specific timestamp are repeatable; the same read at # the same timestamp always returns the same data. If the # timestamp is in the future, the read will block until the # specified timestamp, modulo the read's deadline. # # Useful for large scale consistent reads such as mapreduces, or # for coordinating many reads against a consistent snapshot of the # data. # # A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds. # Example: +"2014-10-02T15:01:23.045123456Z"+. # @!attribute [rw] exact_staleness # @return [Google::Protobuf::Duration] # Executes all reads at a timestamp that is +exact_staleness+ # old. The timestamp is chosen soon after the read is started. # # Guarantees that all writes that have committed more than the # specified number of seconds ago are visible. Because Cloud Spanner # chooses the exact timestamp, this mode works even if the client's # local clock is substantially skewed from Cloud Spanner commit # timestamps. # # Useful for reading at nearby replicas without the distributed # timestamp negotiation overhead of +max_staleness+. # @!attribute [rw] return_read_timestamp # @return [true, false] # If true, the Cloud Spanner-selected read timestamp is included in # the {Google::Spanner::V1::Transaction Transaction} message that describes the transaction. class ReadOnly; end end # A transaction. # @!attribute [rw] id # @return [String] # +id+ may be used to identify the transaction in subsequent # {Google::Spanner::V1::Spanner::Read Read}, # {Google::Spanner::V1::Spanner::ExecuteSql ExecuteSql}, # {Google::Spanner::V1::Spanner::Commit Commit}, or # {Google::Spanner::V1::Spanner::Rollback Rollback} calls. # # Single-use read-only transactions do not have IDs, because # single-use transactions do not support multiple requests. # @!attribute [rw] read_timestamp # @return [Google::Protobuf::Timestamp] # For snapshot read-only transactions, the read timestamp chosen # for the transaction. Not returned by default: see # {Google::Spanner::V1::TransactionOptions::ReadOnly#return_read_timestamp TransactionOptions::ReadOnly#return_read_timestamp}. # # A timestamp in RFC3339 UTC \"Zulu\" format, accurate to nanoseconds. # Example: +"2014-10-02T15:01:23.045123456Z"+. class Transaction; end # This message is used to select the transaction in which a # {Google::Spanner::V1::Spanner::Read Read} or # {Google::Spanner::V1::Spanner::ExecuteSql ExecuteSql} call runs. # # See {Google::Spanner::V1::TransactionOptions TransactionOptions} for more information about transactions. # @!attribute [rw] single_use # @return [Google::Spanner::V1::TransactionOptions] # Execute the read or SQL query in a temporary transaction. # This is the most efficient way to execute a transaction that # consists of a single SQL query. # @!attribute [rw] id # @return [String] # Execute the read or SQL query in a previously-started transaction. # @!attribute [rw] begin # @return [Google::Spanner::V1::TransactionOptions] # Begin a new transaction and execute this read or SQL query in # it. The transaction ID of the new transaction is returned in # {Google::Spanner::V1::ResultSetMetadata#transaction ResultSetMetadata#transaction}, which is a {Google::Spanner::V1::Transaction Transaction}. class TransactionSelector; end end end end