Chapter 07 · DML, Transactions, Read Consistency, Undo, Locks, and Concurrency

Deadlocks, Blocking Sessions, ORA-01555 Snapshot Too Old, Undo Sizing, and Retry Design

Distinguish blocking from deadlock, investigate ORA-00060 and ORA-01555 evidence, and design bounded idempotent retry behavior rather than blind retries.

Advanced125–150 minutesBlocking/deadlock + undo-diagnosis labORA-00060 statement rollback · ORA-01555 designFree · no destructive undo-pressure labLast reviewed: August 2026

Learning outcomes

A ServiceHub incident shows two very different failures under the label “locking”: one request simply waits behind another transaction, while another receives ORA-00060. Separately, a long report fails with ORA-01555 even though no row is locked for reading. Correct diagnosis starts by separating wait cycles from missing undo history.

01

Reproduce and distinguish ordinary blocking from a true deadlock.

02

Explain Oracle deadlock resolution as statement-level rollback and locate trace/alert evidence.

03

Explain ORA-01555 as missing undo needed for a consistent older image.

04

Use V$UNDOSTAT evidence instead of prescribing a universal UNDO_RETENTION value.

05

Design bounded, idempotency-aware retries for transient concurrency failures.

Lab, release, and licensing baseline

Mandatory exercises target the disposable ServiceHub schema in Oracle AI Database Free 26ai. Current documentation was re-checked against RU 23.26.3, SQL Developer 26.2, and SQLcl 26.2. Oracle AI Database Free is limited to 2 foreground CPUs, 2 GB combined SGA/PGA memory, and 12 GB user data and receives no Oracle patches or Support SRs. No paid option, management pack, RAC, Data Guard, Exadata, or cloud service is required. Dynamic performance views shown as observer evidence can require catalog privileges and are clearly separated from application-owner work.

1. Blocking timeline: one waiter, no cycle

sql · setup
DROP TABLE sh07_deadlock_demo IF EXISTS PURGE;CREATE TABLE sh07_deadlock_demo (    work_order_id NUMBER PRIMARY KEY,    status_code   VARCHAR2(12) NOT NULL,    version_no    NUMBER DEFAULT 0 NOT NULL);INSERT INTO sh07_deadlock_demo VALUES (701,'OPEN',0);INSERT INTO sh07_deadlock_demo VALUES (702,'OPEN',0);COMMIT;
sql · Session A holds row 701
UPDATE sh07_deadlock_demoSET version_no = version_no + 1WHERE work_order_id = 701;-- Keep transaction open.
sql · Session B waits for 701
UPDATE sh07_deadlock_demoSET status_code = 'HOLD'WHERE work_order_id = 701;-- Waits. There is no cycle yet.

When Session A commits or rolls back, Session B can continue. That is ordinary blocking. Killing the blocker may be operationally necessary sometimes, but it is not the first diagnostic conclusion.

2. Deadlock timeline: create a cycle deliberately

Reset both sessions with ROLLBACK, then use two different rows. The cycle appears only when each transaction holds one row and requests the other.

Step Session A Session B
1 Update 701; keep open Update 702; keep open
2 Request update 702; waits Still owns 702
3 Owns 701 and waits for 702 Request update 701; cycle forms
sql · Session A
UPDATE sh07_deadlock_demoSET version_no = version_no + 1WHERE work_order_id = 701;UPDATE sh07_deadlock_demoSET status_code = 'HOLD'WHERE work_order_id = 702;-- This second statement waits after Session B has locked 702.
sql · Session B
UPDATE sh07_deadlock_demoSET version_no = version_no + 1WHERE work_order_id = 702;UPDATE sh07_deadlock_demoSET status_code = 'CLOSED'WHERE work_order_id = 701;-- One participant should receive ORA-00060 after the cycle is detected.

Oracle resolves the deadlock by rolling back one statement involved in the cycle and signaling that session. Earlier successful work in that transaction is not automatically rolled back. Production code should normally treat the transaction as suspect and explicitly roll it back unless the business protocol has a carefully proven recovery path.

3. Deadlock evidence: trace first, folklore last

Oracle's error help directs operators to the trace file. The alert log also records ORA-00060 occurrences. From the victim session, a privileged query can locate its default trace file.

sql · diagnostic paths
SELECT name, valueFROM v$diag_infoWHERE name IN ('Default Trace File','Diag Trace');

The deadlock trace describes the resources and sessions participating in the cycle. Use it to determine lock order and SQL involved. Do not “fix” deadlocks by increasing timeouts; a cycle cannot resolve by waiting longer.

4. ORA-01555 is not a row-lock timeout

ORA-01555: snapshot too old means a reader needed undo records to reconstruct an older consistent image, but those undo records had been overwritten. The key dimensions are query age, undo generation rate, available undo space, tuned retention, and whether retention is guaranteed—not the number of row locks held by the query.

Safe-lab policy

This course does not shrink the undo tablespace or generate destructive undo pressure merely to force ORA-01555 on Oracle AI Database Free. The mandatory lab diagnoses the same mechanism from documented statistics. Reproducing ORA-01555 intentionally belongs only in a disposable environment where undo sizing and workload are controlled.

5. Diagnose undo with V$UNDOSTAT

V$UNDOSTAT provides 10-minute interval statistics. Useful columns include undo blocks consumed, transaction count, longest query duration, tuned undo retention, and the snapshot-too-old error count. Use a privileged observer because the application schema should not receive broad performance-view access solely for troubleshooting.

sql · recent undo evidence
SELECT begin_time,       end_time,       undoblks,       txncount,       maxquerylen,       tuned_undoretention,       ssolderrcnt,       nospaceerrcntFROM v$undostatORDER BY begin_time DESCFETCH FIRST 12 ROWS ONLY;

If MAXQUERYLEN approaches or exceeds effective retention while the system generates undo heavily, the risk becomes plausible. UNDO_RETENTION is not a universal guarantee: Oracle documentation explains that under space pressure unexpired undo can be reused unless the undo tablespace uses retention guarantee, which itself trades query protection against the possibility that DML runs out of undo space.

6. Deliberately wrong fixes

Wrong fix 1: commit inside a fetch loop. Repeated commits do not make a long-running query's required snapshot younger; they can complicate cursor processing and increase undo churn. Wrong fix 2: set an enormous UNDO_RETENTION blindly. Retention depends on tablespace sizing and workload, and forcing retention can shift the failure from long queries to writers. Wrong fix 3: retry every ORA error forever. Some errors are deterministic data/logic bugs, and unbounded retries amplify load.

7. Retry design: bounded, classified, and idempotent

For transient concurrency failures that are explicitly classified as retryable, use a bounded retry count, exponential or jittered backoff, fresh transaction state, and an idempotency key or optimistic version check so replay does not duplicate business effects. For ORA-00060, roll back the failed transaction before retrying the business unit unless the design proves a narrower safe recovery.

text · application-level pseudocode
for attempt in 1..MAX_ATTEMPTS:    begin new transaction    try:        apply business change using idempotency_key        commit        return success    except DEADLOCK_OR_RETRYABLE_LOCK_ERROR:        rollback        if attempt == MAX_ATTEMPTS: raise        sleep(backoff_with_jitter(attempt))    except OTHER_ERROR:        rollback        raise

ORA-01555 is usually not solved by immediately retrying the same long query under the same undo pressure. Diagnose query duration, undo consumption, retention, schema/query design, and workload timing first.

8. Cleanup, chapter summary, and bridge

sql · cleanup after both sessions end their transactions
ROLLBACK;DROP TABLE sh07_deadlock_demo PURGE;

Chapter 07 has connected DML to its concurrency machinery: transactions own locks, SCNs define read views, undo reconstructs older versions, blockers are wait dependencies, deadlocks are cycles, and ORA-01555 is a missing-history problem. No AWR/ASH/ADDM or Diagnostics/Tuning Pack is required for the mandatory labs; those licensing-sensitive tools are deferred to later performance chapters. Chapter 08 now builds on this foundation by examining how Oracle indexes change row access paths and DML cost.

Check your understanding

  1. What is the defining difference between blocking and deadlock?
  2. When Oracle resolves ORA-00060, is the whole transaction automatically rolled back?
  3. What does ORA-01555 mean mechanistically?
  4. Why is UNDO_RETENTION alone not always a guarantee?
  5. What properties should a safe retry loop have?
Review the answers

A deadlock contains a cycle of waits; ordinary blocking can be one-way and resolve when the holder ends its transaction.

No. Oracle rolls back one statement involved in the deadlock; earlier transaction work can remain and should be handled explicitly.

The reader needed undo to reconstruct its older consistent image, but the required undo records had been overwritten.

Under space pressure Oracle can reuse unexpired undo unless retention guarantee is enabled; capacity and workload still matter.

Classify only truly transient errors, roll back first, bound attempts, back off with jitter, and make the business operation idempotent or version-checked.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.