<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <p>Transaction isolation in Geode ensures that concurrent transactions execute correctly without interference, maintaining data consistency and integrity. Geode implements full ACID guarantees with configurable isolation levels to balance consistency requirements with performance needs.</p> <h3 id="isolation-fundamentals" class="position-relative d-flex align-items-center group"> <span>Isolation Fundamentals</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="isolation-fundamentals" aria-haspopup="dialog" aria-label="Share link: Isolation Fundamentals"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Transaction isolation prevents concurrent transactions from interfering with each other, addressing phenomena like:</p> <ul> <li><strong>Dirty Reads</strong>: Reading uncommitted changes from other transactions</li> <li><strong>Non-Repeatable Reads</strong>: Reading different values for the same data within a transaction</li> <li><strong>Phantom Reads</strong>: Seeing different sets of rows when repeating a query</li> <li><strong>Lost Updates</strong>: Concurrent updates overwriting each other</li> <li><strong>Write Skew</strong>: Concurrent transactions violating invariants</li> </ul> <p>Geode provides multiple isolation levels to prevent these phenomena based on your application requirements.</p> <h3 id="isolation-levels" class="position-relative d-flex align-items-center group"> <span>Isolation Levels</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="isolation-levels" aria-haspopup="dialog" aria-label="Share link: Isolation Levels"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Geode supports four standard isolation levels defined by the SQL standard, plus an enhanced snapshot isolation level:</p> <h4 id="read-uncommitted" class="position-relative d-flex align-items-center group"> <span>Read Uncommitted</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="read-uncommitted" aria-haspopup="dialog" aria-label="Share link: Read Uncommitted"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Lowest isolation level, allows dirty reads. Not recommended for production use.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Begin</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">read</span><span class="w"> </span><span class="py">uncommitted</span><span class="w"> </span><span class="p">(</span><span class="py">not</span><span class="w"> </span><span class="py">recommended</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">READ</span><span class="w"> </span><span class="py">UNCOMMITTED</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Can</span><span class="w"> </span><span class="py">see</span><span class="w"> </span><span class="py">uncommitted</span><span class="w"> </span><span class="py">changes</span><span class="w"> </span><span class="py">from</span><span class="w"> </span><span class="py">other</span><span class="w"> </span><span class="py">transactions</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Phenomena Prevented</strong>: None <strong>Performance</strong>: Highest <strong>Use Case</strong>: Approximate queries where consistency is not critical</p> <h4 id="read-committed-default" class="position-relative d-flex align-items-center group"> <span>Read Committed (Default)</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="read-committed-default" aria-haspopup="dialog" aria-label="Share link: Read Committed (Default)"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Prevents dirty reads by only reading committed data. Default isolation level in Geode.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Begin</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">read</span><span class="w"> </span><span class="py">committed</span><span class="w"> </span><span class="p">(</span><span class="py">default</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">READ</span><span class="w"> </span><span class="py">COMMITTED</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Only</span><span class="w"> </span><span class="py">sees</span><span class="w"> </span><span class="py">committed</span><span class="w"> </span><span class="py">data</span><span class="p">,</span><span class="w"> </span><span class="py">but</span><span class="w"> </span><span class="py">may</span><span class="w"> </span><span class="py">see</span><span class="w"> </span><span class="py">different</span><span class="w"> </span><span class="py">values</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">repeated</span><span class="w"> </span><span class="py">reads</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$person_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">If</span><span class="w"> </span><span class="py">another</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">commits</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="py">update</span><span class="p">,</span><span class="w"> </span><span class="py">next</span><span class="w"> </span><span class="py">read</span><span class="w"> </span><span class="py">may</span><span class="w"> </span><span class="py">see</span><span class="w"> </span><span class="py">different</span><span class="w"> </span><span class="py">value</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$person_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">May</span><span class="w"> </span><span class="py">return</span><span class="w"> </span><span class="py">different</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Phenomena Prevented</strong>: Dirty reads <strong>Performance</strong>: High <strong>Use Case</strong>: Most applications where consistency within a transaction is needed</p> <h4 id="repeatable-read" class="position-relative d-flex align-items-center group"> <span>Repeatable Read</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="repeatable-read" aria-haspopup="dialog" aria-label="Share link: Repeatable Read"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Prevents dirty reads and non-repeatable reads. Same data returns same values throughout transaction.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Begin</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">repeatable</span><span class="w"> </span><span class="py">read</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">REPEATABLE</span><span class="w"> </span><span class="py">READ</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">First</span><span class="w"> </span><span class="py">read</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$person_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Guaranteed</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">return</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">same</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="py">even</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">another</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">commits</span><span class="w"> </span><span class="py">changes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$person_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Same</span><span class="w"> </span><span class="py">value</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">first</span><span class="w"> </span><span class="py">read</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Phenomena Prevented</strong>: Dirty reads, non-repeatable reads <strong>Performance</strong>: Medium <strong>Use Case</strong>: Reports and analytics requiring consistent snapshots</p> <h4 id="snapshot-isolation-recommended" class="position-relative d-flex align-items-center group"> <span>Snapshot Isolation (Recommended)</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="snapshot-isolation-recommended" aria-haspopup="dialog" aria-label="Share link: Snapshot Isolation (Recommended)"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode&rsquo;s enhanced isolation level using multi-version concurrency control (MVCC). Provides excellent balance of consistency and performance.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Begin</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span><span class="p">(</span><span class="py">recommended</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Sees</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">consistent</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">database</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">start</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">industry</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">technology</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">tech_workers</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Another</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">inserts</span><span class="w"> </span><span class="py">new</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">This</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="nc">still</span><span class="w"> </span><span class="py">sees</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">original</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">WORKS_AT</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">industry</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">technology</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">p</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">tech_workers</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Same</span><span class="w"> </span><span class="py">count</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">before</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Phenomena Prevented</strong>: Dirty reads, non-repeatable reads, phantom reads <strong>Performance</strong>: High (uses MVCC, no read locks) <strong>Use Case</strong>: Most enterprise applications, recommended default</p> <h4 id="serializable" class="position-relative d-flex align-items-center group"> <span>Serializable</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="serializable" aria-haspopup="dialog" aria-label="Share link: Serializable"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Strictest isolation level, guarantees transactions execute as if run serially.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Begin</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">serializable</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">inventory</span><span class="w"> </span><span class="py">level</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">sku</span><span class="p">:</span><span class="w"> </span><span class="nv">$sku</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="nv">$quantity</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Reserve</span><span class="w"> </span><span class="py">inventory</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">sku</span><span class="p">:</span><span class="w"> </span><span class="nv">$sku</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nv">$quantity</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">No</span><span class="w"> </span><span class="py">other</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">can</span><span class="w"> </span><span class="py">modify</span><span class="w"> </span><span class="py">this</span><span class="w"> </span><span class="py">product</span><span class="w"> </span><span class="py">concurrently</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Prevents</span><span class="w"> </span><span class="py">write</span><span class="w"> </span><span class="py">skew</span><span class="w"> </span><span class="py">anomalies</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Phenomena Prevented</strong>: All (dirty reads, non-repeatable reads, phantom reads, write skew) <strong>Performance</strong>: Lower (uses pessimistic locking) <strong>Use Case</strong>: Financial transactions, inventory management, critical operations</p> <h3 id="concurrency-control" class="position-relative d-flex align-items-center group"> <span>Concurrency Control</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="concurrency-control" aria-haspopup="dialog" aria-label="Share link: Concurrency Control"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Geode uses different concurrency control mechanisms depending on isolation level:</p> <h4 id="multi-version-concurrency-control-mvcc" class="position-relative d-flex align-items-center group"> <span>Multi-Version Concurrency Control (MVCC)</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="multi-version-concurrency-control-mvcc" aria-haspopup="dialog" aria-label="Share link: Multi-Version Concurrency Control (MVCC)"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Used for snapshot isolation and repeatable read:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Transaction Timeline: </span></span><span class="line"><span class="cl">T1: BEGIN (snapshot at timestamp 100) </span></span><span class="line"><span class="cl">T2: BEGIN (snapshot at timestamp 101) </span></span><span class="line"><span class="cl">T1: MATCH (p:Person {id: 1}) RETURN p.balance -- Reads version at timestamp 100 </span></span><span class="line"><span class="cl">T2: MATCH (p:Person {id: 1}) SET p.balance = 500 -- Creates new version at timestamp 101 </span></span><span class="line"><span class="cl">T2: COMMIT (version 101 becomes visible) </span></span><span class="line"><span class="cl">T1: MATCH (p:Person {id: 1}) RETURN p.balance -- Still reads version at timestamp 100 </span></span><span class="line"><span class="cl">T1: COMMIT </span></span></code></pre></div><p>Benefits of MVCC:</p> <ul> <li>Readers never block writers</li> <li>Writers never block readers</li> <li>No read locks required</li> <li>Excellent concurrency for read-heavy workloads</li> </ul> <h4 id="pessimistic-locking" class="position-relative d-flex align-items-center group"> <span>Pessimistic Locking</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="pessimistic-locking" aria-haspopup="dialog" aria-label="Share link: Pessimistic Locking"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Used for serializable isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Serializable</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span><span class="py">uses</span><span class="w"> </span><span class="py">locks</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Acquires</span><span class="w"> </span><span class="py">shared</span><span class="w"> </span><span class="py">lock</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">reads</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$account_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Acquires</span><span class="w"> </span><span class="py">exclusive</span><span class="w"> </span><span class="py">lock</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">writes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$account_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">SET</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nv">$amount</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Locks</span><span class="w"> </span><span class="py">held</span><span class="w"> </span><span class="py">until</span><span class="w"> </span><span class="py">commit</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Releases</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">locks</span><span class="w"> </span></span></span></code></pre></div><p>Lock types:</p> <ul> <li><strong>Shared locks (S)</strong>: Multiple transactions can hold shared locks simultaneously for reads</li> <li><strong>Exclusive locks (X)</strong>: Only one transaction can hold an exclusive lock for writes</li> <li><strong>Intent locks</strong>: Hierarchical locks on graphs/nodes to improve performance</li> </ul> <h4 id="optimistic-concurrency-control" class="position-relative d-flex align-items-center group"> <span>Optimistic Concurrency Control</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="optimistic-concurrency-control" aria-haspopup="dialog" aria-label="Share link: Optimistic Concurrency Control"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Used for high-contention scenarios with snapshot isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Optimistic</span><span class="w"> </span><span class="py">approach</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">version</span><span class="w"> </span><span class="py">checking</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Read</span><span class="w"> </span><span class="py">current</span><span class="w"> </span><span class="py">version</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">sku</span><span class="p">:</span><span class="w"> </span><span class="nv">$sku</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">version</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Update</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">version</span><span class="w"> </span><span class="py">check</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">sku</span><span class="p">:</span><span class="w"> </span><span class="nv">$sku</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$expected_version</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">inventory</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$new_inventory</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$expected_version</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">If</span><span class="w"> </span><span class="py">another</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">updated</span><span class="w"> </span><span class="py">first</span><span class="p">,</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">clause</span><span class="w"> </span><span class="py">fails</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">can</span><span class="w"> </span><span class="py">detect</span><span class="w"> </span><span class="py">conflict</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">retry</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="practical-examples" class="position-relative d-flex align-items-center group"> <span>Practical Examples</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="practical-examples" aria-haspopup="dialog" aria-label="Share link: Practical Examples"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="preventing-lost-updates" class="position-relative d-flex align-items-center group"> <span>Preventing Lost Updates</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="preventing-lost-updates" aria-haspopup="dialog" aria-label="Share link: Preventing Lost Updates"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Without proper isolation, concurrent updates can be lost:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Transfer</span><span class="w"> </span><span class="py">from</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span><span class="py">A</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">B</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Balance</span><span class="p">:</span><span class="w"> </span><span class="nv">$1000</span><span class="w"> </span><span class="err">-&gt;</span><span class="w"> </span><span class="nv">$900</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Transfer</span><span class="w"> </span><span class="py">from</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span><span class="py">A</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">C</span><span class="w"> </span><span class="p">(</span><span class="py">concurrent</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">50</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Reads</span><span class="w"> </span><span class="nv">$1000</span><span class="p">,</span><span class="w"> </span><span class="py">sets</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="nv">$950</span><span class="w"> </span><span class="p">(</span><span class="py">loses</span><span class="w"> </span><span class="py">T1</span><span class="err">&#39;</span><span class="py">s</span><span class="w"> </span><span class="py">update</span><span class="p">!)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Use proper isolation to prevent:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">serializable</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="py">blocks</span><span class="w"> </span><span class="py">until</span><span class="w"> </span><span class="py">T1</span><span class="w"> </span><span class="py">completes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Waits</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">T1</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">commit</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">50</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Now</span><span class="w"> </span><span class="py">correctly</span><span class="w"> </span><span class="py">sees</span><span class="w"> </span><span class="nv">$900</span><span class="p">,</span><span class="w"> </span><span class="py">sets</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="nv">$850</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="preventing-phantom-reads" class="position-relative d-flex align-items-center group"> <span>Preventing Phantom Reads</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="preventing-phantom-reads" aria-haspopup="dialog" aria-label="Share link: Preventing Phantom Reads"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Count</span><span class="w"> </span><span class="py">high</span><span class="err">-</span><span class="py">value</span><span class="w"> </span><span class="py">customers</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">READ</span><span class="w"> </span><span class="py">COMMITTED</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">lifetime_value</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">10000</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">c</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">5</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Add</span><span class="w"> </span><span class="py">new</span><span class="w"> </span><span class="py">high</span><span class="err">-</span><span class="py">value</span><span class="w"> </span><span class="py">customer</span><span class="w"> </span><span class="p">(</span><span class="py">concurrent</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(:</span><span class="nc">Customer</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">New</span><span class="w"> </span><span class="py">VIP</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">lifetime_value</span><span class="p">:</span><span class="w"> </span><span class="nc">15000</span><span class="p">})</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Repeat</span><span class="w"> </span><span class="py">count</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">lifetime_value</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">10000</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">c</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">6</span><span class="w"> </span><span class="p">(</span><span class="py">phantom</span><span class="w"> </span><span class="py">read</span><span class="p">!)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Prevent with snapshot isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">lifetime_value</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">10000</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">c</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">5</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Add</span><span class="w"> </span><span class="py">new</span><span class="w"> </span><span class="py">high</span><span class="err">-</span><span class="py">value</span><span class="w"> </span><span class="py">customer</span><span class="w"> </span><span class="p">(</span><span class="py">concurrent</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(:</span><span class="nc">Customer</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">New</span><span class="w"> </span><span class="py">VIP</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">lifetime_value</span><span class="p">:</span><span class="w"> </span><span class="nc">15000</span><span class="p">})</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Repeat</span><span class="w"> </span><span class="py">count</span><span class="w"> </span><span class="py">sees</span><span class="w"> </span><span class="py">same</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Customer</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">lifetime_value</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">10000</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">c</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Still</span><span class="w"> </span><span class="py">returns</span><span class="w"> </span><span class="py">5</span><span class="w"> </span><span class="p">(</span><span class="py">no</span><span class="w"> </span><span class="py">phantom</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="preventing-write-skew" class="position-relative d-flex align-items-center group"> <span>Preventing Write Skew</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="preventing-write-skew" aria-haspopup="dialog" aria-label="Share link: Preventing Write Skew"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Write skew occurs when concurrent transactions read overlapping data and make conflicting updates:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Constraint</span><span class="p">:</span><span class="w"> </span><span class="nc">At</span><span class="w"> </span><span class="py">least</span><span class="w"> </span><span class="kd">on</span><span class="py">e</span><span class="w"> </span><span class="py">doctor</span><span class="w"> </span><span class="py">must</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Initially</span><span class="p">:</span><span class="w"> </span><span class="nc">Doctor</span><span class="w"> </span><span class="py">A</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">B</span><span class="w"> </span><span class="py">are</span><span class="w"> </span><span class="py">both</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Doctor</span><span class="w"> </span><span class="py">A</span><span class="w"> </span><span class="py">goes</span><span class="w"> </span><span class="py">off</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Doctor</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">2</span><span class="p">,</span><span class="w"> </span><span class="py">seems</span><span class="w"> </span><span class="py">safe</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">go</span><span class="w"> </span><span class="py">off</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">da</span><span class="p">:</span><span class="nc">Doctor</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">Dr</span><span class="err">.</span><span class="w"> </span><span class="py">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">da</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">false</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Now</span><span class="w"> </span><span class="kd">on</span><span class="py">ly</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">doctor</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">call</span><span class="w"> </span><span class="p">(</span><span class="py">still</span><span class="w"> </span><span class="py">safe</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Doctor</span><span class="w"> </span><span class="py">B</span><span class="w"> </span><span class="py">goes</span><span class="w"> </span><span class="py">off</span><span class="w"> </span><span class="py">call</span><span class="w"> </span><span class="p">(</span><span class="py">concurrent</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Doctor</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">2</span><span class="p">,</span><span class="w"> </span><span class="py">seems</span><span class="w"> </span><span class="py">safe</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">go</span><span class="w"> </span><span class="py">off</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">db</span><span class="p">:</span><span class="nc">Doctor</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">Dr</span><span class="err">.</span><span class="w"> </span><span class="py">B</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">db</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">false</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Now</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">doctors</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">call</span><span class="w"> </span><span class="p">(</span><span class="py">constraint</span><span class="w"> </span><span class="py">violated</span><span class="p">!)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Prevent with serializable isolation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">serializable</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Doctor</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">2</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">da</span><span class="p">:</span><span class="nc">Doctor</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">Dr</span><span class="err">.</span><span class="w"> </span><span class="py">A</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">da</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">false</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="py">blocks</span><span class="w"> </span><span class="py">until</span><span class="w"> </span><span class="py">T1</span><span class="w"> </span><span class="py">completes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Doctor</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="kd">on</span><span class="py">_call</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Returns</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="p">(</span><span class="py">after</span><span class="w"> </span><span class="py">T1</span><span class="w"> </span><span class="py">committed</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Sees</span><span class="w"> </span><span class="py">constraint</span><span class="w"> </span><span class="py">would</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">violated</span><span class="p">,</span><span class="w"> </span><span class="py">can</span><span class="w"> </span><span class="py">abort</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ROLLBACK</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="configuration" class="position-relative d-flex align-items-center group"> <span>Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="configuration" aria-haspopup="dialog" aria-label="Share link: Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="setting-default-isolation-level" class="position-relative d-flex align-items-center group"> <span>Setting Default Isolation Level</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="setting-default-isolation-level" aria-haspopup="dialog" aria-label="Share link: Setting Default Isolation Level"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Set default isolation level for all connections</span> </span></span><span class="line"><span class="cl">geode serve --default-isolation-level<span class="o">=</span>snapshot </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Per-connection isolation level</span> </span></span><span class="line"><span class="cl">geode shell --isolation-level<span class="o">=</span>serializable </span></span></code></pre></div> <h4 id="isolation-level-per-session" class="position-relative d-flex align-items-center group"> <span>Isolation Level Per Session</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="isolation-level-per-session" aria-haspopup="dialog" aria-label="Share link: Isolation Level Per Session"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Change</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span><span class="py">level</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">current</span><span class="w"> </span><span class="py">session</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">All</span><span class="w"> </span><span class="py">subsequent</span><span class="w"> </span><span class="py">transactions</span><span class="w"> </span><span class="py">use</span><span class="w"> </span><span class="py">snapshot</span><span class="w"> </span><span class="py">isolation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Reset</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">default</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">DEFAULT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="deadlock-detection" class="position-relative d-flex align-items-center group"> <span>Deadlock Detection</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="deadlock-detection" aria-haspopup="dialog" aria-label="Share link: Deadlock Detection"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Configure deadlock detection</span> </span></span><span class="line"><span class="cl">geode serve --deadlock-detection<span class="o">=</span>enabled <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --deadlock-timeout<span class="o">=</span>10s <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --deadlock-retry-attempts<span class="o">=</span><span class="m">3</span> </span></span></code></pre></div><p>When deadlock is detected:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">acquires</span><span class="w"> </span><span class="py">locks</span><span class="w"> </span><span class="py">that</span><span class="w"> </span><span class="py">create</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">deadlock</span><span class="w"> </span><span class="py">cycle</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">detects</span><span class="w"> </span><span class="py">deadlock</span><span class="w"> </span><span class="py">after</span><span class="w"> </span><span class="py">timeout</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Error</span><span class="p">:</span><span class="w"> </span><span class="nc">Deadlock</span><span class="w"> </span><span class="py">detected</span><span class="p">,</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">aborted</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Application</span><span class="w"> </span><span class="py">should</span><span class="w"> </span><span class="py">retry</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">ISOLATION</span><span class="w"> </span><span class="py">LEVEL</span><span class="w"> </span><span class="py">SERIALIZABLE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Retry</span><span class="w"> </span><span class="py">logic</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="performance-considerations" class="position-relative d-flex align-items-center group"> <span>Performance Considerations</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-considerations" aria-haspopup="dialog" aria-label="Share link: Performance Considerations"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="choosing-the-right-isolation-level" class="position-relative d-flex align-items-center group"> <span>Choosing the Right Isolation Level</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="choosing-the-right-isolation-level" aria-haspopup="dialog" aria-label="Share link: Choosing the Right Isolation Level"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><table> <thead> <tr> <th>Isolation Level</th> <th>Read Throughput</th> <th>Write Throughput</th> <th>Latency</th> <th>Consistency</th> </tr> </thead> <tbody> <tr> <td>Read Uncommitted</td> <td>Highest</td> <td>Highest</td> <td>Lowest</td> <td>Lowest</td> </tr> <tr> <td>Read Committed</td> <td>High</td> <td>High</td> <td>Low</td> <td>Medium</td> </tr> <tr> <td>Repeatable Read</td> <td>Medium</td> <td>Medium</td> <td>Medium</td> <td>High</td> </tr> <tr> <td>Snapshot</td> <td>High</td> <td>High</td> <td>Low</td> <td>High</td> </tr> <tr> <td>Serializable</td> <td>Low</td> <td>Low</td> <td>High</td> <td>Highest</td> </tr> </tbody> </table> <h4 id="performance-best-practices" class="position-relative d-flex align-items-center group"> <span>Performance Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-best-practices" aria-haspopup="dialog" aria-label="Share link: Performance Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li><strong>Use Snapshot Isolation for most workloads</strong>: Best balance of consistency and performance</li> <li><strong>Reserve Serializable for critical operations</strong>: Financial transactions, inventory management</li> <li><strong>Keep transactions short</strong>: Reduces lock contention and blocking</li> <li><strong>Read before write</strong>: Minimize time holding write locks</li> <li><strong>Batch operations</strong>: Group related updates into single transaction</li> <li><strong>Avoid long-running transactions</strong>: Can block other transactions and prevent garbage collection</li> </ol> <h4 id="monitoring-isolation-performance" class="position-relative d-flex align-items-center group"> <span>Monitoring Isolation Performance</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="monitoring-isolation-performance" aria-haspopup="dialog" aria-label="Share link: Monitoring Isolation Performance"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Monitor transaction statistics</span> </span></span><span class="line"><span class="cl">geode stats --component<span class="o">=</span>transactions <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --metrics<span class="o">=</span>isolation_level,conflicts,retries,deadlocks </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Example output:</span> </span></span><span class="line"><span class="cl"><span class="c1"># Isolation Level | Transactions | Conflicts | Retries | Deadlocks</span> </span></span><span class="line"><span class="cl"><span class="c1"># READ_COMMITTED | 1,234,567 | 45 | 12 | 0</span> </span></span><span class="line"><span class="cl"><span class="c1"># SNAPSHOT | 5,678,901 | 234 | 67 | 0</span> </span></span><span class="line"><span class="cl"><span class="c1"># SERIALIZABLE | 123,456 | 1,234 | 456 | 12</span> </span></span></code></pre></div> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="high-conflict-rate" class="position-relative d-flex align-items-center group"> <span>High Conflict Rate</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="high-conflict-rate" aria-haspopup="dialog" aria-label="Share link: High Conflict Rate"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>If seeing many conflicts with snapshot/serializable isolation:</p> <ol> <li><strong>Reduce transaction scope</strong>: Break large transactions into smaller ones</li> <li><strong>Increase retry logic</strong>: Implement exponential backoff for retries</li> <li><strong>Consider read committed</strong>: If strict consistency not required</li> <li><strong>Partition data</strong>: Reduce contention by sharding hot data</li> </ol> <h4 id="deadlocks" class="position-relative d-flex align-items-center group"> <span>Deadlocks</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="deadlocks" aria-haspopup="dialog" aria-label="Share link: Deadlocks"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>If experiencing deadlocks:</p> <ol> <li><strong>Access resources in consistent order</strong>: Always lock nodes/relationships in same order</li> <li><strong>Reduce lock hold time</strong>: Keep transactions as short as possible</li> <li><strong>Lower isolation level</strong>: Use snapshot instead of serializable if possible</li> <li><strong>Implement retry logic</strong>: Automatically retry deadlocked transactions</li> </ol> <h4 id="performance-degradation" class="position-relative d-flex align-items-center group"> <span>Performance Degradation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-degradation" aria-haspopup="dialog" aria-label="Share link: Performance Degradation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>If isolation causing performance issues:</p> <ol> <li><strong>Profile transactions</strong>: Identify which transactions are slowest</li> <li><strong>Reduce isolation level</strong>: Use lowest level that meets consistency requirements</li> <li><strong>Optimize queries</strong>: Ensure efficient query plans to reduce lock time</li> <li><strong>Scale horizontally</strong>: Add more replicas for read-heavy workloads</li> </ol> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/transactions/" >Transactions</a> - Transaction management and ACID properties</li> <li><a href="/tags/data-integrity/" >Data Integrity</a> - Ensuring data consistency</li> <li><a href="/tags/sessions/" >Sessions</a> - Session management and connection settings</li> <li><a href="/tags/configuration/" >Configuration</a> - Transaction configuration options</li> <li><a href="/tags/performance/" >Performance</a> - Performance tuning and optimization</li> <li><a href="/docs/transactions/advanced-patterns/" >Transaction Patterns</a> - Advanced transaction patterns</li> </ul>

Related Articles