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:
releaseissuesRELEASE SAVEPOINTand 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.rollbackissuesROLLBACK TO SAVEPOINTand 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>
impl<'t> SavepointOp<'t>
Sourcepub async fn release(self) -> Result<(), Error>
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.
Sourcepub async fn rollback(self) -> Result<(), Error>
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<'_>
impl AtomicOperation for SavepointOp<'_>
Source§fn commit_hook<H: CommitHook>(&self) -> Option<&H>
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>>
fn maybe_now(&self) -> Option<DateTime<Utc>>
Source§fn clock(&self) -> &ClockHandle
fn clock(&self) -> &ClockHandle
Source§fn connection(&mut self) -> &mut Connection
fn connection(&mut self) -> &mut Connection
Source§fn add_commit_hook<H: CommitHook>(&mut self, hook: H) -> Result<(), H>
fn add_commit_hook<H: CommitHook>(&mut self, hook: H) -> Result<(), H>
Source§fn supports_hooks(&self) -> bool
fn supports_hooks(&self) -> bool
Source§fn as_executor(&mut self) -> OneTimeExecutor<'_, &mut Connection>
fn as_executor(&mut self) -> OneTimeExecutor<'_, &mut Connection>
sqlx::Executor implementation that statements should be
executed through. Read moreAuto 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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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