Skip to main content

SavepointOp

Struct SavepointOp 

Source
pub struct SavepointOp<'t> { /* private fields */ }
Expand description

An AtomicOperation scoped to a database SAVEPOINT inside a parent DbOp.

Created by DbOp::with_savepoint / DbOp::begin_savepoint. Statements executed through it run inside the savepoint, so they can be undone with rollback without poisoning — or ending — the parent transaction. This is what makes a “loop over N items in one transaction, but isolate each item’s failure” pattern possible: one COMMIT (one WAL flush) for the whole batch, while a failing item unwinds only its own writes.

§Hooks are staged, not executed

Commit hooks registered on a SavepointOp — including the ones repositories register internally, e.g. via post_persist_hook — are staged in a private buffer rather than added to the parent operation:

  • release issues RELEASE SAVEPOINT and then folds the staged hooks into the parent’s buffer through the ordinary registration/merge path, exactly as if they had been registered on the parent directly.
  • rollback issues ROLLBACK TO SAVEPOINT and drops the staged hooks. A rolled-back item therefore contributes zero hook state to match its zero database state — no phantom event publishes, no inserts referencing rows that no longer exist.

No hook’s pre_commit / post_commit ever runs at savepoint boundaries. They run once, at the parent’s commit, over the final merged hook set — so post_commit still only fires after a durable COMMIT, and on_rollback still only fires when the whole transaction is gone.

Implementations§

Source§

impl<'t> SavepointOp<'t>

Source

pub async fn release(self) -> Result<(), Error>

Releases the savepoint, keeping this scope’s work.

Issues RELEASE SAVEPOINT, then folds the staged commit hooks into the parent operation’s buffer via the normal registration/merge path — so a mergeable hook type accumulates across savepoints exactly as it would have on the parent, and a non-mergeable one lands at its own position in release order.

If the RELEASE itself fails the staged hooks are dropped and the error is returned: the parent transaction is in an indeterminate state and the caller must abandon it rather than commit.

Source

pub async fn rollback(self) -> Result<(), Error>

Rolls back to the savepoint, discarding this scope’s work.

Issues ROLLBACK TO SAVEPOINT and drops the staged commit hooks. The parent transaction stays alive and usable — including after an error that would otherwise have poisoned it.

Dropping a SavepointOp without calling either release or rollback has the same database effect (sqlx queues the rollback on the connection) and likewise discards the staged hooks.

Trait Implementations§

Source§

impl AtomicOperation for SavepointOp<'_>

Source§

fn commit_hook<H: CommitHook>(&self) -> Option<&H>

Reads the staged buffer first, falling back to the parent’s.

While a savepoint is open the two are not yet merged, so a hook type present in both reports only the staged instance here — they become one hook when the savepoint is released.

Source§

fn maybe_now(&self) -> Option<DateTime<Utc>>

Function for querying when the operation is taking place - if it is cached.
Source§

fn clock(&self) -> &ClockHandle

Returns the clock handle for time operations. Read more
Source§

fn connection(&mut self) -> &mut Connection

Returns the raw underlying connection. The desired way to represent this would actually be as a GAT: Read more
Source§

fn add_commit_hook<H: CommitHook>(&mut self, hook: H) -> Result<(), H>

Registers a commit hook that will run pre_commit before and post_commit after the transaction commits. Returns Ok(()) if the hook was registered, Err(hook) if hooks are not supported.
Source§

fn supports_hooks(&self) -> bool

Whether this operation supports commit hooks. Read more
Source§

fn as_executor(&mut self) -> OneTimeExecutor<'_, &mut Connection>

Returns the sqlx::Executor implementation that statements should be executed through. Read more

Auto Trait Implementations§

§

impl<'t> !RefUnwindSafe for SavepointOp<'t>

§

impl<'t> !Sync for SavepointOp<'t>

§

impl<'t> !UnwindSafe for SavepointOp<'t>

§

impl<'t> Freeze for SavepointOp<'t>

§

impl<'t> Send for SavepointOp<'t>

§

impl<'t> Unpin for SavepointOp<'t>

§

impl<'t> UnsafeUnpin for SavepointOp<'t>

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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