Three resources — a Lock, a DB Connection, and a File Handle —
need to be released in reverse order, even when the work between them throws. Pick a cleanup
style, then run the happy path or the throwing path and watch what actually gets disposed.
function process() {
using lock = acquireLock();
using db = openConnection();
using file = openFile();
doWork(); // may throw
}
// scope exits — normally OR via throw — and
// file, then db, then lock dispose automatically, in reverse order.
function process() { const lock = acquireLock(); const db = openConnection(); const file = openFile(); try { doWork(); // may throw file.dispose(); // only reached if doWork() succeeds db.dispose(); // only reached if doWork() succeeds } finally { // lock.dispose(); <- forgotten entirely } }
Acquisition order: Lock → DB Connection → File Handle. Correct disposal always reverses that: File Handle → DB Connection → Lock.
Every resource opens in the same order either way. Watch which ones a thrown error skips, and which one manual code simply never remembers to close.