---
title: Write claim application changes
summary: Runs the subclass save path inside an Oracle transaction, committing on success and rolling back on failure.
status: draft
owner: Technical Writer
last_reviewed: 2026-07-30
library: SAIF.Application.Claim
reference_type: package
operation_id: OP-AC-04
trigger: Caller invokes Write() to persist pending application changes
---

# Write claim application changes

`Write()` wraps the subclass-specific save logic in an Oracle transaction so that either all pending changes commit together or none of them do. It is the transactional counterpart to [Retrieve claim application data](retrieve-claim-application-data.md).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-AC-04 |
| **Trigger** | Caller calls `Write()` on an active `ClaimAppManager` subclass instance |
| **Inputs** | Pending in-memory changes accumulated by the subclass since the last save |
| **Outputs** | Boolean commit/rollback result; committed or rolled-back Oracle transaction |
| **Primary components** | `ClaimAppManager.Write`, `ClaimAppManager.OnTransactionStart`, `ClaimAppManager.OnWrite`, `ClaimAppManager.OnTransactionStop`, `IDataPortalInfo` |
| **Entry point** | `Application\SAIF.Application.Claim\ClaimAppManager.vb` |

## Steps

1. `Write()` initializes a local `WriteResult` to `False`.
2. `Write()` calls `OnTransactionStart()` before attempting any subclass save logic.
   - `OnTransactionStart()` checks `DPI.TransactionPending`; if it is false, it calls `DataLayer.DAL.BeginTransaction(DPI.PortalID)` to open a new Oracle transaction. If a transaction is already pending, no new transaction is started.
3. Inside a `Try` block, `Write()` calls `OnWrite()` and assigns its result to `WriteResult`.
   - `OnWrite()` is abstract in `ClaimAppManager`; the concrete subclass performs its own business-object save calls here.
   - On an exception during `OnWrite()`: the `Catch` block calls `OnTransactionStop(False)` (forcing a rollback) and then re-throws the caught exception via `Throw ex`, which resets the original stack trace to this catch block rather than preserving the original throw location.*
4. The `Finally` block calls `OnTransactionStop(WriteResult)` unconditionally, whether or not an exception occurred.
   - `OnTransactionStop(inCommit)` checks `DPI.TransactionPending`; if a transaction is pending, it calls `DataLayer.DAL.EndTransaction(DPI.PortalID, inCommit)`, committing when `inCommit` is true and rolling back when it is false.
   - Because the `Catch` block already called `OnTransactionStop(False)` on failure, the `Finally` block's subsequent call finds no transaction pending (from the perspective of `DPI.TransactionPending`) and is effectively a no-op on the exception path.*
5. `Write()` returns `WriteResult` as the overall success indicator.

## Process flow

The following diagram visualizes the transaction-wrapped save sequence, including the exception path.

```mermaid
flowchart TD
	Start([Caller invokes Write]) --> TxStart[OnTransactionStart:<br>begin transaction if none pending]
	TxStart --> OnWrite[OnWrite in subclass]
	OnWrite -->|Success| SetResult[WriteResult = OnWrite result]
	OnWrite -->|Exception| Rollback[OnTransactionStop False;<br>rethrow exception]
	SetResult --> Finally[Finally: OnTransactionStop WriteResult]
	Rollback --> Finally
	Finally --> Commit{WriteResult True?}
	Commit -->|Yes| Committed([Transaction committed])
	Commit -->|No| RolledBack([Transaction rolled back<br>or exception propagates])
```

## Failure and edge-case behavior

- If `OnWrite()` throws, the transaction is rolled back immediately in the `Catch` block and the original exception is re-thrown to the caller — callers must handle the propagated exception themselves; `Write()` does not swallow it.
- Re-throwing with `Throw ex` (rather than a bare `Throw`) resets the stack trace, which can make root-cause diagnosis harder for callers inspecting the exception.*
- If `OnTransactionStart()` finds a transaction already pending (`DPI.TransactionPending = True`), it does not begin a new one — nested `Write()` calls share the same outer transaction rather than each managing their own.*
- `OnWrite()` has no base-class implementation; a subclass that does not override it will have `WriteResult` remain at its default `False`, and the transaction will always roll back.*

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

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

## Sources

- `Application\SAIF.Application.Claim\ClaimAppManager.vb`
