---
title: Rollback
summary: Rolls back the active transaction, then disposes the session when the rollback call itself does not throw.
status: draft
owner: Framework
last_reviewed: 2026-10-02
library: SAIF.NetCore.NHibernate
reference_type: package
operation_id: OP-NH-09
trigger: Consumer calls IUnitOfWork.Rollback()
---

# Rollback

This operation reverses the unit of work's transaction and — unlike [Commit](commit.md) — tears down the session afterward on the normal (non-throwing) path, since there is no `try`/`finally` guarding the disposal call.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-NH-09 |
| **Trigger** | Consumer calls `IUnitOfWork.Rollback()` |
| **Inputs** | — |
| **Outputs** | Transaction rolled back if it was active; session disposed only when `transaction.Rollback()` itself does not throw |
| **Primary components** | `UnitOfWork.Rollback` |
| **Entry point** | `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs` |

## Steps

1. Read `Session.Transaction()`.
2. If `transaction.IsActive` is `true`: call `transaction.Rollback()`.
   - If `transaction.IsActive` is `false`: do nothing here — unlike [Commit](commit.md), `Rollback` does **not** throw when no transaction is active.
3. If `transaction.Rollback()` did not throw, call `Session.Dispose()` next. There is **no `try`/`finally`** around the rollback call: if `transaction.Rollback()` itself throws, `Session.Dispose()` is skipped entirely and the exception propagates to the caller — `Rollback()` provides no exception-safety guarantee that cleanup always runs ([BR-NH-14](../business-rules.md#br-nh-14-rollback-disposes-the-session-only-when-rollback-itself-does-not-throw)).
4. `Rollback()` does **not** set the `isDisposed` flag — only `UnitOfWork.Dispose()`/`Dispose(bool)` does that. Calling `Rollback()` and later `Dispose()` still runs the full disposal logic in [Dispose unit of work](dispose-unit-of-work.md); disposal is not skipped just because `Rollback()` ran first.

## Process flow

The diagram below visualizes the active-transaction check, the rollback-throws vs. rollback-succeeds paths, and the session-disposal step that only the non-throwing path reaches.

```mermaid
flowchart TD
	Start(["Rollback() called"]) --> Check{"transaction.IsActive?"}
	Check -->|Yes| DoRollback["transaction.Rollback()"]
	Check -->|No| Skip["No rollback performed<br>(no exception thrown)"]
	DoRollback -->|"throws"| Propagate(["Exception propagates;<br>Session.Dispose() skipped"])
	DoRollback -->|"succeeds"| DisposeSession["Session.Dispose()"]
	Skip --> DisposeSession
	DisposeSession --> Return(["Session disposed on this path"])
```

## Failure and edge-case behavior
- Calling `Rollback()` with no active transaction does not throw — it still proceeds to dispose the session (per step 3). This is asymmetric with [Commit](commit.md), which throws in that same situation.*
- When `transaction.Rollback()` succeeds (or no rollback was needed), `Session.Dispose()` runs. Whether a subsequent call on the unit of work fails is not guaranteed by this page: the stateful session strategy's `Session` getter can transparently reopen a closed-but-not-fully-disposed session (see [ISessionStrategy](../api/SAIF.NetCore.NHibernate.Interfaces/ISessionStrategy.md)), so "the session is now closed" does not necessarily mean every further call fails — the exact behavior of further calls after disposal depends on strategy and is not fully characterized here.**
- When `transaction.Rollback()` throws, `Session.Dispose()` is skipped (no try/finally) and the exception propagates before any disposal occurs. Whether the session is consequently left in a reusable or broken state is not confirmed by this library's own source — this library does not prove either outcome.**
- `Rollback()` does not set `isDisposed`, so calling [Dispose unit of work](dispose-unit-of-work.md) after `Rollback()` still runs its full disposal logic rather than being skipped — see that page for the exact flag-order and `IsNull()`-side-effect caveats.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Begin transaction](begin-transaction.md)
- [Commit](commit.md)
- [Dispose unit of work](dispose-unit-of-work.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs`
