Skip to content

Commit

This operation commits the transaction opened by the most recent Begin transaction, then calls Session.Clear() to clear the session's first-level cache/tracking. Clear() is not a flush: whether pending changes were actually synchronized to the database by this point depends on the session's FlushMode, which this library does not set.

Field Value
Operation ID OP-NH-08
Trigger Consumer calls IUnitOfWork.Commit()
Inputs —
Outputs Committed transaction; cleared session, or a thrown exception
Primary components UnitOfWork.Commit
Entry point src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs

Steps

  1. Read Session.Transaction().
  2. If transaction.IsActive is false: throw InvalidOperationException("You must call Begin() on the unit of work before you can commit.") (BR-NH-13)
  3. If active: call transaction.Commit().
  4. Call Session.Clear() after a successful commit. On the stateful strategy this discards the first-level cache so subsequent reads on the same session hit the database again. On the stateless strategy, Clear() is a literal no-op — a stateless session has no first-level cache to discard, and its Add/Update/Delete calls already write immediately rather than queuing changes for a flush-at-commit, so Commit() there is effectively a COMMIT-only operation with no equivalent cache-clearing effect.

Commit contains no literal SQL text in this library's own source, but that does not mean no database activity occurs: transaction.Commit() is a call into NHibernate's ITransaction, which internally issues a database COMMIT and, for a stateful session, triggers NHibernate's auto-flush of any pending INSERT/UPDATE/DELETE changes before committing — subject to the session's own externally-configured FlushMode (for example FlushMode.Never/Manual would suppress the implicit flush); this is not an unconditional guarantee independent of session configuration. For a stateless session there is no such flush step, because stateless Add/Update/Delete operations already execute immediately against the database rather than being queued. This is NHibernate/ADO.NET provider behavior external to this library's own source — well-known NHibernate transaction semantics, but not something this repository's source directly confirms since it doesn't ship NHibernate's own source.* Commit is also the final step of Test connection's Begin/query/Commit cycle, which does execute SQL-004.

Process flow

The diagram below visualizes the active-transaction check, the commit/session-clear path, and the thrown-exception path when no transaction is active.

flowchart TD
    Start(["Commit() called"]) --> Check{"transaction.IsActive?"}
    Check -->|No| Throw(["Throw InvalidOperationException"])
    Check -->|Yes| DoCommit["transaction.Commit()"]
    DoCommit --> ClearSession["Session.Clear()<br>(stateful: discards cache; stateless: no-op)"]
    ClearSession --> Return(["Transaction committed"])

Failure and edge-case behavior

  • Calling Commit() without a preceding successful Begin(), or after the transaction has already been committed or rolled back, throws InvalidOperationException with message "You must call Begin() on the unit of work before you can commit.".
  • Commit() does not dispose the session. Against NHibernate 5.2.7, a successful commit detaches the completed transaction from the session (ConnectionManager.AfterTransaction() sets _transaction = null), so a later Begin transaction on the same unit of work starts a new transaction and does not throw. A second Commit() without a new Begin() throws, as described above, because the session's current transaction is then a new, inactive one.
  • Session.Clear() after commit means entities loaded before the commit become detached; reusing them without reattachment can raise lazy-loading exceptions. This applies to the stateful strategy only — the stateless strategy's Clear() is a no-op, and stateless sessions never hold first-level-cached entities to detach in the first place.*

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs
  • NHibernate 5.2.7 (resolved via FluentNHibernate 3.0.1): src/NHibernate/Transaction/AdoTransaction.cs (Commit, AfterTransactionCompletion), src/NHibernate/AdoNet/ConnectionManager.cs (AfterTransaction, Transaction)