Skip to main content

BatchIsolation

Trait BatchIsolation 

Source
pub trait BatchIsolation: SavepointOperation {
    // Provided methods
    fn run_isolated<'a, T, V, E, F>(
        &'a mut self,
        items: &'a [T],
        f: F,
    ) -> impl Future<Output = Result<Vec<Result<V, E>>, Error>> + 'a
       where T: 'a,
             V: 'a,
             E: 'a,
             F: AsyncFnOnce(&mut SavepointOp<'_>, &T) -> Result<V, E> + Clone + Sync + 'a { ... }
    fn run_bisected<'a, T, E, F>(
        &'a mut self,
        items: &'a [T],
        budget: BisectBudget,
        f: F,
    ) -> impl Future<Output = Result<BisectOutcomes<E>, Error>> + 'a
       where T: 'a,
             E: Error + 'static,
             F: AsyncFnOnce(&mut SavepointOp<'_>, &[T]) -> Result<(), E> + Clone + Sync + 'a { ... }
    fn run_bisected_with<'a, T, E, F, P>(
        &'a mut self,
        items: &'a [T],
        budget: BisectBudget,
        policy: TransientPolicy<P>,
        f: F,
    ) -> impl Future<Output = Result<BisectOutcomes<E>, Error>> + 'a
       where T: 'a,
             E: Display + 'a,
             P: Fn(&E) -> bool + 'a,
             F: AsyncFnOnce(&mut SavepointOp<'_>, &[T]) -> Result<(), E> + Clone + Sync + 'a { ... }
}
Expand description

Batch isolation for every AtomicOperation.

Blanket-implemented, like SavepointOperation, so DbOp, SavepointOp (nesting), HookOperation, and operation types defined outside this crate all get it without naming a concrete type — and so a function generic over impl AtomicOperation can use it.

Provided Methods§

Source

fn run_isolated<'a, T, V, E, F>( &'a mut self, items: &'a [T], f: F, ) -> impl Future<Output = Result<Vec<Result<V, E>>, Error>> + 'a
where T: 'a, V: 'a, E: 'a, F: AsyncFnOnce(&mut SavepointOp<'_>, &T) -> Result<V, E> + Clone + Sync + 'a,

Runs f once per item, each inside its own SAVEPOINT, in item order.

A failing item unwinds only its own writes and staged hooks; the transaction stays usable and the loop continues, so its healthy batch-mates still commit. Outcomes are returned positionally: one entry per input, f’s own Ok/Err preserved.

The outer Err(sqlx::Error) means the savepoint machinery itself failed, leaving the enclosing transaction in an indeterminate state: abandon it.

Source

fn run_bisected<'a, T, E, F>( &'a mut self, items: &'a [T], budget: BisectBudget, f: F, ) -> impl Future<Output = Result<BisectOutcomes<E>, Error>> + 'a
where T: 'a, E: Error + 'static, F: AsyncFnOnce(&mut SavepointOp<'_>, &[T]) -> Result<(), E> + Clone + Sync + 'a,

Probes the whole slice at once, bisecting only on failure.

The happy path costs one probe. On failure the slice splits and pending ranges are probed largest-first (earliest start breaking ties) until budget is spent, so clean siblings are salvaged and a culprit resolves from its own single-item probe, where its error is attributable to it.

Deadlock victims and serialization failures re-probe the same range unsplit and are refunded to the budget — see TransientPolicy. Use run_bisected_with to widen that class.

Source

fn run_bisected_with<'a, T, E, F, P>( &'a mut self, items: &'a [T], budget: BisectBudget, policy: TransientPolicy<P>, f: F, ) -> impl Future<Output = Result<BisectOutcomes<E>, Error>> + 'a
where T: 'a, E: Display + 'a, P: Fn(&E) -> bool + 'a, F: AsyncFnOnce(&mut SavepointOp<'_>, &[T]) -> Result<(), E> + Clone + Sync + 'a,

run_bisected with a caller-supplied notion of which failures are transient.

Classification being the caller’s, the error bound here is just Display.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§