Skip to main content

Transaction ownership and failure cuts

What this concept is​

A transaction boundary groups database effects under a stated success and failure contract. The function in this lab owns one transaction on an idle connection: an order and its audit row appear together, or neither new row appears. Previously committed work remains unchanged.

Why it matters here​

If an order insert succeeds and the audit insert fails, committing the first statement alone violates the operation contract. Catching an exception without rolling back can leave partial state or an open transaction for the next caller.

Concrete example​

Order 90 and its audit are already committed. Creating order 91 has two statements. Inject failure after the order insert: only order 90 and its audit remain. Inject failure after the audit insert but before commit: the same result must hold. Without an injected failure, both 90 and 91 and their audit rows remain. These three outcomes are observable with queries, not inferred from a success message.

Common confusion / misconception​

The exercise does not establish that every possible crash is safe, that two clients are serializable, or that retrying after a lost response is harmless. An exception inside one process is a different failure model from power loss. This function rejects an existing caller transaction rather than committing or rolling back someone else’s work.

How to use it​

Use a connection configured with isolation_level=None so explicit BEGIN/COMMIT/ROLLBACK ownership is visible. Check in_transaction before BEGIN, bind values as parameters, and propagate failures after rollback. Keep schema setup outside the operation. Inject at named statement boundaries and check both tables plus connection state. Capture constraints as a second source of failure, not just the synthetic exceptions.

Check yourself​

If the client times out after COMMIT, can the client infer whether the order exists? Where would a durable unique request identity fit, and which additional concurrent interleavings would need testing?

Mini drill or application​

Write the no-transaction version in a separate disposable database and observe the surviving order after failure following statement one. Then start a caller transaction and show that the guarded function rejects it without closing that transaction. Explain why an automatic retry is not part of this API.

Read this only if stuck​

Use the transaction sections of Database System Concepts, then reconnect the result to Semester 05’s distinction between durability and observed acknowledgment. Concurrency-control implementation belongs to Module 4; keep that future question explicit.