Struct ReadWriteTransaction

Source
pub struct ReadWriteTransaction { /* private fields */ }
Expand description

ReadWriteTransaction provides a locking read-write transaction.

This type of transaction is the only way to write data into Cloud Spanner; Client::apply, Client::apply_at_least_once, Client::partitioned_update use transactions internally. These transactions rely on pessimistic locking and, if necessary, two-phase commit. Locking read-write transactions may abort, requiring the application to retry. However, the interface exposed by Client:run_with_retry eliminates the need for applications to write retry loops explicitly.

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. 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 a commit.

See Client::run_with_retry for an example.

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.

Aborted transactions

Application code does not need to retry explicitly; RunInTransaction will automatically retry a transaction if an attempt results in an abort. The lock priority of a transaction increases after each prior aborted transaction, meaning that the next attempt has a slightly better chance of success than before.

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.

Implementations§

Source§

impl ReadWriteTransaction

Source

pub async fn begin( session: ManagedSession, options: CallOptions, transaction_tag: Option<String>, ) -> Result<ReadWriteTransaction, BeginError>

Source

pub async fn begin_partitioned_dml( session: ManagedSession, options: CallOptions, transaction_tag: Option<String>, ) -> Result<ReadWriteTransaction, BeginError>

Source

pub fn buffer_write(&mut self, ms: Vec<Mutation>)

Source

pub async fn update(&mut self, stmt: Statement) -> Result<i64, Status>

Source

pub async fn update_with_option( &mut self, stmt: Statement, options: QueryOptions, ) -> Result<i64, Status>

Source

pub async fn batch_update( &mut self, stmt: Vec<Statement>, ) -> Result<Vec<i64>, Status>

Source

pub async fn batch_update_with_option( &mut self, stmt: Vec<Statement>, options: QueryOptions, ) -> Result<Vec<i64>, Status>

Source

pub async fn end<S, E>( &mut self, result: Result<S, E>, options: Option<CommitOptions>, ) -> Result<(CommitResult, S), E>
where E: TryAs<Status> + From<Status>,

Methods from Deref<Target = Transaction>§

Source

pub async fn query( &mut self, statement: Statement, ) -> Result<RowIterator<'_, impl Reader>, Status>

query executes a query against the database. It returns a RowIterator for retrieving the resulting rows.

query returns only row data, without a query plan or execution statistics.

Source

pub async fn query_with_option( &mut self, statement: Statement, options: QueryOptions, ) -> Result<RowIterator<'_, impl Reader>, Status>

query executes a query against the database. It returns a RowIterator for retrieving the resulting rows.

query returns only row data, without a query plan or execution statistics.

Source

pub async fn read( &mut self, table: &str, columns: &[&str], key_set: impl Into<KeySet>, ) -> Result<RowIterator<'_, impl Reader>, Status>

read returns a RowIterator for reading multiple rows from the database.

use google_cloud_spanner::key::Key;
use google_cloud_spanner::client::{Client, Error};

#[tokio::main]
async fn run(client: Client) -> Result<(), Error> {
    let mut tx = client.single().await?;
    let mut iter = tx.read("Guild", &["GuildID", "OwnerUserID"], vec![
        Key::new(&"pk1"),
        Key::new(&"pk2")
    ]).await?;

    while let Some(row) = iter.next().await? {
        let guild_id = row.column_by_name::<String>("GuildID");
        //do something
    };
    Ok(())
}
Source

pub async fn read_with_option( &mut self, table: &str, columns: &[&str], key_set: impl Into<KeySet>, options: ReadOptions, ) -> Result<RowIterator<'_, impl Reader>, Status>

read returns a RowIterator for reading multiple rows from the database.

Source

pub async fn read_row( &mut self, table: &str, columns: &[&str], key: Key, ) -> Result<Option<Row>, Status>

read returns a RowIterator for reading multiple rows from the database.

use google_cloud_spanner::key::Key;
use google_cloud_spanner::client::Client;
use google_cloud_spanner::client::Error;

async fn run(client: Client) -> Result<(), Error> {
    let mut tx = client.single().await?;
    let row = tx.read_row("Guild", &["GuildID", "OwnerUserID"], Key::new(&"guild1")).await?;
    Ok(())
}
Source

pub async fn read_row_with_option( &mut self, table: &str, columns: &[&str], key: Key, options: ReadOptions, ) -> Result<Option<Row>, Status>

read returns a RowIterator for reading multiple rows from the database.

Trait Implementations§

Source§

impl Deref for ReadWriteTransaction

Source§

type Target = Transaction

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for ReadWriteTransaction

Source§

fn deref_mut(&mut self) -> &mut Transaction

Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,