<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Acid on IT Comparison</title><link>https://comparison.metacog.co.kr/tags/acid/</link><description>Recent content in Acid on IT Comparison</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 06 Sep 2026 09:47:51 +0900</lastBuildDate><atom:link href="https://comparison.metacog.co.kr/tags/acid/index.xml" rel="self" type="application/rss+xml"/><item><title>Serializable vs Weaker Isolation: Strict Ordering vs Controlled Anomalies</title><link>https://comparison.metacog.co.kr/posts/2026-09-06-serializable-vs-weaker-isolation-strict-ordering-vs-controll/</link><pubDate>Sun, 06 Sep 2026 09:47:51 +0900</pubDate><guid>https://comparison.metacog.co.kr/posts/2026-09-06-serializable-vs-weaker-isolation-strict-ordering-vs-controll/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Serializable isolation guarantees that concurrent transactions produce a result equivalent to some &lt;strong class="kw"&gt;serial order&lt;/strong&gt;, eliminating every possible race condition. Weaker isolation levels like Read Committed or Snapshot trade that guarantee for higher throughput, deliberately allowing certain &lt;strong class="kw"&gt;read/write anomalies&lt;/strong&gt; that application code must tolerate or guard against.&lt;/p&gt;
&lt;h2 id="comparison-diagram"&gt;Comparison Diagram&lt;/h2&gt;
&lt;div class="compare-diagram"&gt;
&lt;svg viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg"&gt;&lt;line x1="320" y1="20" x2="320" y2="340" style="stroke:var(--border)" stroke-width="1" stroke-dasharray="4 4"/&gt;&lt;text x="160" y="36" text-anchor="middle" style="fill:var(--primary)" font-size="18" font-weight="600"&gt;Serializable&lt;/text&gt;&lt;text x="480" y="36" text-anchor="middle" style="fill:var(--primary)" font-size="18" font-weight="600"&gt;Weaker Isolation&lt;/text&gt;&lt;line x1="40" y1="180" x2="280" y2="180" style="stroke:var(--border)" stroke-width="1"/&gt;&lt;line x1="360" y1="180" x2="600" y2="180" style="stroke:var(--border)" stroke-width="1"/&gt;&lt;rect x="45" y="110" width="100" height="36" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="95" y="133" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;T1&lt;/text&gt;&lt;rect x="175" y="110" width="100" height="36" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="225" y="133" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;T2&lt;/text&gt;&lt;path d="M40 200 L280 200" style="stroke:var(--compare-a)" stroke-width="2" marker-end="url(#arrowA)"/&gt;&lt;text x="160" y="225" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;time (T1 fully precedes T2)&lt;/text&gt;&lt;text x="160" y="260" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;No overlap in effect =&lt;/text&gt;&lt;text x="160" y="278" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;equivalent to a serial run&lt;/text&gt;&lt;rect x="45" y="100" width="140" height="36" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5" transform="translate(340,0)"/&gt;&lt;text x="455" y="123" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;T1&lt;/text&gt;&lt;rect x="115" y="144" width="140" height="36" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5" transform="translate(340,0)"/&gt;&lt;text x="525" y="167" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;T2&lt;/text&gt;&lt;rect x="455" y="100" width="45" height="80" style="fill:none;stroke:var(--compare-b)" stroke-width="1" stroke-dasharray="3 3"/&gt;&lt;path d="M360 200 L600 200" style="stroke:var(--compare-b)" stroke-width="2" marker-end="url(#arrowB)"/&gt;&lt;text x="480" y="225" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;time (T1 and T2 overlap)&lt;/text&gt;&lt;text x="480" y="260" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;Overlap window =&lt;/text&gt;&lt;text x="480" y="278" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;dirty/non-repeatable reads,&lt;/text&gt;&lt;text x="480" y="296" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;phantoms, or write skew possible&lt;/text&gt;&lt;defs&gt;&lt;marker id="arrowA" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto"&gt;&lt;path d="M0 0 L8 4 L0 8 z" style="fill:var(--compare-a)"/&gt;&lt;/marker&gt;&lt;marker id="arrowB" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto"&gt;&lt;path d="M0 0 L8 4 L0 8 z" style="fill:var(--compare-b)"/&gt;&lt;/marker&gt;&lt;/defs&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;h2 id="comparison-table"&gt;Comparison Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Serializable&lt;/th&gt;
&lt;th&gt;Weaker Isolation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Isolation guarantee&lt;/td&gt;
&lt;td&gt;Result equivalent to some serial execution of all transactions&lt;/td&gt;
&lt;td&gt;Allows specific interleavings; guarantee varies by level (Read Committed, Repeatable Read, Snapshot)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency control&lt;/td&gt;
&lt;td&gt;Full conflict serializability via strict two-phase locking, serializable snapshot isolation (SSI), or predicate locks&lt;/td&gt;
&lt;td&gt;Row-level locks or MVCC snapshots that only block on narrower conflict sets (e.g. write-write)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anomalies prevented&lt;/td&gt;
&lt;td&gt;Dirty reads, non-repeatable reads, phantom reads, and write skew all eliminated&lt;/td&gt;
&lt;td&gt;Only a subset prevented; phantoms and write skew commonly remain possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contention behavior&lt;/td&gt;
&lt;td&gt;Higher rate of lock waits, deadlocks, or serialization-failure aborts under concurrent access&lt;/td&gt;
&lt;td&gt;Readers rarely block writers (MVCC) or lower lock scope, so contention is reduced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput impact&lt;/td&gt;
&lt;td&gt;Lower throughput and higher latency as concurrency increases, especially with hot rows&lt;/td&gt;
&lt;td&gt;Higher throughput and better scalability under contention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application responsibility&lt;/td&gt;
&lt;td&gt;Application can assume correctness; only needs to retry on serialization-failure errors&lt;/td&gt;
&lt;td&gt;Application must reason about anomalies and add explicit checks (e.g. version columns, SELECT FOR UPDATE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conflict detection timing&lt;/td&gt;
&lt;td&gt;Detected either at lock-acquisition time or at commit time (optimistic serializable schemes)&lt;/td&gt;
&lt;td&gt;Detected only for the narrower conflicts the level covers, often just at commit for MVCC writes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default in major databases&lt;/td&gt;
&lt;td&gt;Rarely the default; must be explicitly requested (e.g. SET TRANSACTION ISOLATION LEVEL SERIALIZABLE)&lt;/td&gt;
&lt;td&gt;Default in most systems out of the box (PostgreSQL/Oracle default to Read Committed, MySQL InnoDB to Repeatable Read)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key Differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Serializable enforces true &lt;strong class="kw"&gt;serial equivalence&lt;/strong&gt;; weaker levels only rule out a defined subset of anomalies.&lt;/li&gt;
&lt;li&gt;Weaker isolation relies on &lt;strong class="kw"&gt;MVCC snapshots&lt;/strong&gt; or narrow locks, cutting contention compared to serializable&amp;rsquo;s broader locking or SSI conflict tracking.&lt;/li&gt;
&lt;li&gt;Under Serializable, correctness bugs shift into &lt;strong class="kw"&gt;retry loops&lt;/strong&gt; on abort; under weaker levels, they shift into missed application-level checks.&lt;/li&gt;
&lt;li&gt;Write skew is the classic anomaly Serializable closes that even &lt;strong class="kw"&gt;Snapshot Isolation&lt;/strong&gt; leaves open.&lt;/li&gt;
&lt;li&gt;Choosing a level is a runtime trade-off between guaranteed correctness and &lt;strong class="kw"&gt;throughput&lt;/strong&gt;, not a one-time schema decision.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-to-use-each"&gt;When to Use Each&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Serializable&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>