@@ -306,26 +306,26 @@ def is_nested_sequence(obj: object) -> bool:
306306
307307class Transaction:
308308 """
309- A context manager for transactional operations with failure and success callbacks.
309+ A context manager for transactional operations with failure and exit callbacks.
310310
311311 Failure callbacks are executed in LIFO order if the transaction exits without being committed.
312- Success callbacks are executed in FIFO order when the transaction is committed .
312+ Exit callbacks always run: in LIFO order on rollback or FIFO order during commit .
313313
314314 Usage:
315315 with Transaction() as txn:
316316 txn.on_failure(some_cleanup_function , arg1 , arg2 )
317- txn.on_success (some_finalize_function , arg1 , arg2 )
317+ txn.on_exit (some_finalize_function , arg1 , arg2 )
318318 # ... perform operations ...
319319 txn.commit()
320320
321321 Methods:
322322 on_failure(fn , *args , **kwargs ): Register a callback to be called on rollback.
323- on_success (fn, * args, ** kwargs): Register a callback to be called on commit.
324- commit(): Disarm failure callbacks and run success callbacks.
323+ on_exit (fn, * args, ** kwargs): Register a callback to be called on rollback or commit.
324+ commit(): Disarm failure callbacks and run exit callbacks.
325325 """
326326 def __init__(self) -> None:
327327 self._stack = ExitStack()
328- self._on_success : list[Callable[[], Any]] = []
328+ self._on_exit : list[Callable[[], Any]] = []
329329 self._entered = False
330330
331331 def __enter__(self):
@@ -336,7 +336,7 @@ class Transaction:
336336 def __exit__(self, exc_type, exc, tb):
337337 # If exit callbacks remain, they'll run in LIFO order.
338338 self._entered = False
339- self._on_success .clear()
339+ self._on_exit .clear()
340340 return self._stack.__exit__(exc_type, exc, tb)
341341
342342 def on_failure(self, fn: Callable[..., Any], /, *args: Any, **kwargs: Any) -> None:
@@ -348,24 +348,26 @@ class Transaction:
348348 raise RuntimeError("Transaction must be entered before on_failure()")
349349 self._stack.callback(partial(fn, *args, **kwargs))
350350
351- def on_success (self, fn: Callable[..., Any], /, *args: Any, **kwargs: Any) -> None:
351+ def on_exit (self, fn: Callable[..., Any], /, *args: Any, **kwargs: Any) -> None:
352352 """
353- Register a success callback (runs in FIFO order during commit()).
353+ Register an exit callback (runs exactly once, on rollback or during commit()).
354354 Values are bound now via partial so late mutations don' t bite you.
355355 """
356356 if not self._entered:
357- raise RuntimeError("Transaction must be entered before on_success()")
358- self._on_success.append(partial(fn, *args, **kwargs))
357+ raise RuntimeError("Transaction must be entered before on_exit()")
358+ callback = partial(fn, *args, **kwargs)
359+ self._stack.callback(callback)
360+ self._on_exit.append(callback)
359361
360362 def commit(self) -> None:
361363 """
362- Disarm all failure callbacks, then run success callbacks in FIFO order.
364+ Disarm all failure callbacks, then run exit callbacks in FIFO order.
363365 """
364366 # pop_all() empties this stack so no callbacks are triggered on exit.
365367 self._stack.pop_all()
366- for fn in self._on_success :
368+ for fn in self._on_exit :
367369 fn()
368- self._on_success .clear()
370+ self._on_exit .clear()
369371
370372
371373# Track whether we've already warned about fork method
0 commit comments