File size: 17,024 Bytes
f91a684 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | import { motion } from 'motion/react';
export default function ACIDTransactionsDiagram() {
return (
<motion.div
initial={{ opacity: 0, y: 24, scale: 0.97 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{ duration: 0.7, ease: [0.25, 0.1, 0.25, 1] as const, delay: 0.2 }}
className="mt-10 mb-4"
>
<div className="text-center mb-6">
<span className="text-lg font-bold uppercase tracking-widest text-indigo-400" style={{ filter: 'drop-shadow(0 0 10px rgba(99,102,241,0.5))' }}>
TRANSACTIONS & ACID PROPERTIES
</span>
</div>
<svg viewBox="0 0 900 760" className="w-full max-w-6xl mx-auto" style={{ filter: 'drop-shadow(0 0 30px rgba(99,102,241,0.1))' }}>
<defs>
<marker id="acidArr" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#6366f1" /></marker>
<marker id="acidRed" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#ef4444" /></marker>
<marker id="acidGrn" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#22c55e" /></marker>
<linearGradient id="acidHdr" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stopColor="rgba(99,102,241,0.2)" /><stop offset="100%" stopColor="rgba(99,102,241,0.05)" /></linearGradient>
</defs>
{/* Header */}
<rect x="20" y="10" width="860" height="48" rx="12" fill="url(#acidHdr)" stroke="rgba(99,102,241,0.4)" strokeWidth="2" />
<ellipse cx="50" cy="26" rx="13" ry="5" fill="none" stroke="#6366f1" strokeWidth="1.5" />
<rect x="37" y="26" width="26" height="14" fill="rgba(99,102,241,0.1)" />
<ellipse cx="50" cy="40" rx="13" ry="5" fill="none" stroke="#6366f1" strokeWidth="1.5" />
<text x="72" y="28" fill="#818cf8" fontSize="10" fontWeight="700" fontFamily="'Inter',sans-serif">Transaction:</text>
<text x="148" y="28" fill="#a5b4fc" fontSize="9" fontFamily="'Inter',sans-serif">A sequence of database operations treated as a single logical unit of work.</text>
<text x="72" y="42" fill="#a5b4fc" fontSize="9" fontFamily="'Inter',sans-serif">All operations must succeed together, or all must fail β enforced by ACID properties.</text>
{/* Lifecycle */}
<text x="450" y="80" textAnchor="middle" fill="#e2e8f0" fontSize="10" fontWeight="800" fontFamily="'Inter',sans-serif">TRANSACTION LIFECYCLE</text>
{[
{ x: 30, label: 'BEGIN', c: '#6366f1' },
{ x: 195, label: 'ACTIVE', c: '#22c55e' },
{ x: 360, label: 'PARTIALLY COMMITTED', c: '#3b82f6' },
{ x: 560, label: 'COMMITTED', c: '#4ade80' },
].map(({ x, label, c }, i) => (
<g key={i}>
<rect x={x} y="88" width="140" height="30" rx="7" fill={`${c}22`} stroke={`${c}88`} strokeWidth="1.5" />
<text x={x + 70} y="107" textAnchor="middle" fill={c} fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">{label}</text>
</g>
))}
<line x1="170" y1="103" x2="195" y2="103" stroke="#6366f1" strokeWidth="1.5" markerEnd="url(#acidArr)" />
<line x1="335" y1="103" x2="360" y2="103" stroke="#6366f1" strokeWidth="1.5" markerEnd="url(#acidArr)" />
<line x1="500" y1="103" x2="560" y2="103" stroke="#22c55e" strokeWidth="1.5" markerEnd="url(#acidGrn)" />
<rect x="360" y="128" width="110" height="26" rx="7" fill="rgba(239,68,68,0.12)" stroke="rgba(239,68,68,0.4)" strokeWidth="1.5" />
<text x="415" y="144" textAnchor="middle" fill="#f87171" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">FAILED β ROLLBACK</text>
<line x1="430" y1="118" x2="430" y2="128" stroke="#ef4444" strokeWidth="1.5" markerEnd="url(#acidRed)" />
{/* A β Atomicity */}
<rect x="20" y="168" width="420" height="220" rx="12" fill="rgba(34,197,94,0.06)" stroke="rgba(34,197,94,0.4)" strokeWidth="2" />
<circle cx="44" cy="192" r="14" fill="#22c55e" />
<text x="44" y="197" textAnchor="middle" fill="white" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">A</text>
<text x="68" y="189" fill="#4ade80" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">ATOMICITY</text>
<text x="68" y="202" fill="#86efac" fontSize="8" fontFamily="'Inter',sans-serif">"All or Nothing"</text>
<text x="24" y="222" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">Every op in a transaction succeeds, or the entire</text>
<text x="24" y="234" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">transaction is rolled back with no partial changes.</text>
<text x="24" y="252" fill="#4ade80" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Example: Bank Transfer βΉ500 from A β B</text>
<rect x="24" y="259" width="175" height="80" rx="6" fill="rgba(34,197,94,0.08)" stroke="rgba(34,197,94,0.3)" strokeWidth="1" />
<text x="111" y="274" textAnchor="middle" fill="#4ade80" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">β SUCCESS (COMMIT)</text>
<text x="34" y="290" fill="#86efac" fontSize="7.5" fontFamily="'Inter',sans-serif">1. Debit A: -βΉ500 β</text>
<text x="34" y="303" fill="#86efac" fontSize="7.5" fontFamily="'Inter',sans-serif">2. Credit B: +βΉ500 β</text>
<text x="34" y="316" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">Both written to disk</text>
<text x="34" y="330" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">A: βΉ1000ββΉ500 B: βΉ200ββΉ700</text>
<rect x="215" y="259" width="195" height="80" rx="6" fill="rgba(239,68,68,0.08)" stroke="rgba(239,68,68,0.3)" strokeWidth="1" />
<text x="312" y="274" textAnchor="middle" fill="#f87171" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">β FAILURE (ROLLBACK)</text>
<text x="225" y="290" fill="#fca5a5" fontSize="7.5" fontFamily="'Inter',sans-serif">1. Debit A: -βΉ500 β</text>
<text x="225" y="303" fill="#f87171" fontSize="7.5" fontFamily="'Inter',sans-serif">2. Credit B: ERROR β</text>
<text x="225" y="316" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">Entire tx rolled back</text>
<text x="225" y="330" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">A stays βΉ1000, B stays βΉ200</text>
<text x="24" y="365" fill="#fbbf24" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">Enforced by:</text>
<text x="90" y="365" fill="#94a3b8" fontSize="8" fontFamily="'Inter',sans-serif">Undo logs & Rollback mechanism</text>
<text x="24" y="378" fill="#fbbf24" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">Ops:</text>
<rect x="50" y="369" width="55" height="14" rx="4" fill="rgba(34,197,94,0.2)" stroke="rgba(34,197,94,0.4)" strokeWidth="1" />
<text x="77" y="379" textAnchor="middle" fill="#4ade80" fontSize="7" fontFamily="'Inter',sans-serif">COMMIT</text>
<rect x="112" y="369" width="62" height="14" rx="4" fill="rgba(239,68,68,0.2)" stroke="rgba(239,68,68,0.4)" strokeWidth="1" />
<text x="143" y="379" textAnchor="middle" fill="#f87171" fontSize="7" fontFamily="'Inter',sans-serif">ROLLBACK</text>
{/* C β Consistency */}
<rect x="460" y="168" width="420" height="220" rx="12" fill="rgba(59,130,246,0.06)" stroke="rgba(59,130,246,0.4)" strokeWidth="2" />
<circle cx="484" cy="192" r="14" fill="#3b82f6" />
<text x="484" y="197" textAnchor="middle" fill="white" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">C</text>
<text x="508" y="189" fill="#60a5fa" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">CONSISTENCY</text>
<text x="508" y="202" fill="#93c5fd" fontSize="8" fontFamily="'Inter',sans-serif">"Valid State to Valid State"</text>
<text x="468" y="222" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">A transaction brings the DB from one valid state</text>
<text x="468" y="234" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">to another β all integrity constraints are preserved.</text>
<text x="468" y="252" fill="#60a5fa" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Integrity Constraints that must hold:</text>
<rect x="468" y="258" width="390" height="95" rx="6" fill="rgba(15,23,42,0.4)" stroke="rgba(59,130,246,0.2)" strokeWidth="1" />
{[
{ k: 'NOT NULL', v: 'Required fields must always have values', y: 0 },
{ k: 'UNIQUE', v: 'No duplicates in constrained columns', y: 1 },
{ k: 'CHECK', v: 'e.g. balance β₯ 0 β no negative balances', y: 2 },
{ k: 'FOREIGN KEY', v: 'Referenced rows must exist in parent table', y: 3 },
{ k: 'PRIMARY KEY', v: 'Must be unique and non-null', y: 4 },
].map(({ k, v, y }) => (
<g key={y}>
<rect x="474" y={266 + y * 17} width="70" height="12" rx="3" fill="rgba(59,130,246,0.15)" stroke="rgba(59,130,246,0.3)" strokeWidth="0.5" />
<text x="509" y={275 + y * 17} textAnchor="middle" fill="#93c5fd" fontSize="6.5" fontWeight="700" fontFamily="'Inter',sans-serif">{k}</text>
<text x="550" y={275 + y * 17} fill="#94a3b8" fontSize="7" fontFamily="'Inter',sans-serif">{v}</text>
</g>
))}
<text x="468" y="368" fill="#60a5fa" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">Violation β transaction aborted automatically.</text>
<text x="468" y="381" fill="#94a3b8" fontSize="7.5" fontFamily="'Inter',sans-serif">Consistency is the responsibility of both DB & application.</text>
{/* I β Isolation */}
<rect x="20" y="400" width="420" height="340" rx="12" fill="rgba(168,85,247,0.06)" stroke="rgba(168,85,247,0.4)" strokeWidth="2" />
<circle cx="44" cy="424" r="14" fill="#a855f7" />
<text x="44" y="429" textAnchor="middle" fill="white" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">I</text>
<text x="68" y="421" fill="#c084fc" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">ISOLATION</text>
<text x="68" y="434" fill="#d8b4fe" fontSize="8" fontFamily="'Inter',sans-serif">"Transactions Don't Interfere"</text>
<text x="24" y="455" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">Concurrent transactions run as if they are serial.</text>
<text x="24" y="467" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">Intermediate states are hidden from other transactions.</text>
<text x="24" y="487" fill="#c084fc" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Isolation Levels (weakest β strongest):</text>
<rect x="24" y="494" width="385" height="92" rx="6" fill="rgba(15,23,42,0.4)" stroke="rgba(168,85,247,0.2)" strokeWidth="1" />
{[
{ lv: 'READ UNCOMMITTED', note: 'Dirty Read allowed', c: '#f87171' },
{ lv: 'READ COMMITTED', note: 'Prevents Dirty Read', c: '#fbbf24' },
{ lv: 'REPEATABLE READ', note: 'Prevents Non-repeatable Read', c: '#60a5fa' },
{ lv: 'SERIALIZABLE', note: 'Prevents Phantom Read β safest', c: '#4ade80' },
].map(({ lv, note, c }, i) => (
<g key={i}>
<rect x="30" y={500 + i * 21} width="160" height="14" rx="3" fill={`${c}20`} stroke={`${c}40`} strokeWidth="0.5" />
<text x="110" y={510 + i * 21} textAnchor="middle" fill={c} fontSize="6.5" fontWeight="700" fontFamily="'Inter',sans-serif">{lv}</text>
<text x="198" y={510 + i * 21} fill="#94a3b8" fontSize="7" fontFamily="'Inter',sans-serif">{note}</text>
</g>
))}
<text x="24" y="600" fill="#c084fc" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Read Phenomena:</text>
<text x="24" y="616" fill="#94a3b8" fontSize="8" fontFamily="'Inter',sans-serif">β’ Dirty Read: sees uncommitted data of another tx</text>
<text x="24" y="630" fill="#94a3b8" fontSize="8" fontFamily="'Inter',sans-serif">β’ Non-repeatable Read: same query returns different rows</text>
<text x="24" y="644" fill="#94a3b8" fontSize="8" fontFamily="'Inter',sans-serif">β’ Phantom Read: new rows appear in a repeated range query</text>
<text x="24" y="660" fill="#fbbf24" fontSize="7.5" fontFamily="'Inter',sans-serif">Implemented via: Locks, MVCC (Multi-Version Concurrency Control)</text>
<text x="24" y="673" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">Higher isolation = more serializable but lower concurrency performance.</text>
<text x="24" y="686" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">Most DBs default to READ COMMITTED or REPEATABLE READ.</text>
<text x="24" y="730" fill="#94a3b8" fontSize="7.5" fontFamily="'Inter',sans-serif">PostgreSQL: defaults to READ COMMITTED | MySQL InnoDB: REPEATABLE READ</text>
{/* D β Durability */}
<rect x="460" y="400" width="420" height="340" rx="12" fill="rgba(245,158,11,0.06)" stroke="rgba(245,158,11,0.4)" strokeWidth="2" />
<circle cx="484" cy="424" r="14" fill="#f59e0b" />
<text x="484" y="429" textAnchor="middle" fill="white" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">D</text>
<text x="508" y="421" fill="#fbbf24" fontSize="13" fontWeight="800" fontFamily="'Inter',sans-serif">DURABILITY</text>
<text x="508" y="434" fill="#fcd34d" fontSize="8" fontFamily="'Inter',sans-serif">"Committed = Permanent"</text>
<text x="468" y="455" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">Once a transaction commits, changes persist forever</text>
<text x="468" y="467" fill="#e2e8f0" fontSize="8.5" fontFamily="'Inter',sans-serif">β even across crashes, power failures, or errors.</text>
<text x="468" y="487" fill="#fbbf24" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Techniques that ensure Durability:</text>
<rect x="468" y="494" width="385" height="92" rx="6" fill="rgba(15,23,42,0.4)" stroke="rgba(245,158,11,0.2)" strokeWidth="1" />
{[
{ t: 'Write-Ahead Logging (WAL)', d: 'Log changes before applying to disk' },
{ t: 'Checkpointing', d: 'Periodically flush dirty pages to storage' },
{ t: 'Redo Logs', d: 'Replay committed txs after a crash' },
{ t: 'Shadow Paging', d: 'Keep old page until commit is confirmed' },
].map(({ t, d }, i) => (
<g key={i}>
<text x="478" y={507 + i * 22} fill="#fbbf24" fontSize="7.5" fontWeight="700" fontFamily="'Inter',sans-serif">βΈ {t}</text>
<text x="478" y={518 + i * 22} fill="#94a3b8" fontSize="7" fontFamily="'Inter',sans-serif"> {d}</text>
</g>
))}
<text x="468" y="600" fill="#fbbf24" fontSize="8.5" fontWeight="700" fontFamily="'Inter',sans-serif">Crash Recovery Flow:</text>
{[
{ label: 'CRASH', c: '#ef4444', x: 468 },
{ label: 'READ REDO LOG', c: '#fbbf24', x: 560 },
{ label: 'REPLAY COMMITS', c: '#3b82f6', x: 665 },
{ label: 'DB RESTORED β', c: '#4ade80', x: 775 },
].map(({ label, c, x }, i) => (
<g key={i}>
<rect x={x} y="608" width="88" height="22" rx="5" fill={`${c}20`} stroke={`${c}50`} strokeWidth="1" />
<text x={x + 44} y="622" textAnchor="middle" fill={c} fontSize="6.5" fontWeight="700" fontFamily="'Inter',sans-serif">{label}</text>
{i < 3 && <line x1={x + 88} y1="619" x2={x + 100} y2="619" stroke={c} strokeWidth="1.5" markerEnd="url(#acidArr)" />}
</g>
))}
<text x="468" y="648" fill="#94a3b8" fontSize="8" fontFamily="'Inter',sans-serif">WAL ensures that crash recovery restores all committed changes.</text>
<text x="468" y="660" fill="#4ade80" fontSize="8" fontWeight="700" fontFamily="'Inter',sans-serif">Committed transactions are ALWAYS recoverable.</text>
<text x="468" y="680" fill="#94a3b8" fontSize="7.5" fontFamily="'Inter',sans-serif">Used in: PostgreSQL (WAL), MySQL (InnoDB redo log),</text>
<text x="468" y="692" fill="#94a3b8" fontSize="7.5" fontFamily="'Inter',sans-serif">Oracle (REDO log files), SQL Server (Transaction Log)</text>
<text x="468" y="712" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">Storage media: SSDs and HDDs provide physical durability.</text>
<text x="468" y="724" fill="#64748b" fontSize="7" fontFamily="'Inter',sans-serif">For distributed systems: replication adds cross-node durability.</text>
<text x="468" y="740" fill="#fbbf24" fontSize="7.5" fontWeight="700" fontFamily="'Inter',sans-serif">Summary: ACID = the gold standard for reliable database transactions.</text>
</svg>
</motion.div>
);
}
|