<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <p>Transaction management is a cornerstone of Geode&rsquo;s enterprise-ready architecture. Unlike many graph databases that sacrifice consistency for performance, Geode provides full ACID guarantees with Serializable Snapshot Isolation (SSI), ensuring your data remains consistent even under high concurrency and complex workloads.</p> <p>Geode&rsquo;s transaction system is built on Multi-Version Concurrency Control (MVCC), which enables high-performance concurrent access without locking readers. Combined with Write-Ahead Logging (WAL) for durability and savepoint support for complex transaction logic, Geode delivers the reliability and correctness required for mission-critical applications.</p> <p>This comprehensive guide explores transaction concepts, usage patterns, and best practices for leveraging Geode&rsquo;s transaction capabilities effectively.</p> <h3 id="core-transaction-concepts" class="position-relative d-flex align-items-center group"> <span>Core Transaction Concepts</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="core-transaction-concepts" aria-haspopup="dialog" aria-label="Share link: Core Transaction Concepts"> <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><strong>ACID Guarantees</strong>: Geode enforces all four ACID properties:</p> <ul> <li><strong>Atomicity</strong>: Transactions execute completely or not at all</li> <li><strong>Consistency</strong>: Transactions maintain all integrity constraints</li> <li><strong>Isolation</strong>: Concurrent transactions don&rsquo;t interfere with each other</li> <li><strong>Durability</strong>: Committed changes survive system failures</li> </ul> <p><strong>Serializable Snapshot Isolation (SSI)</strong>: Geode implements the strongest isolation level, preventing all anomalies including phantom reads, non-repeatable reads, and serialization anomalies. Your transactions execute as if they were run serially, even when running concurrently.</p> <p><strong>Multi-Version Concurrency Control (MVCC)</strong>: Instead of locking, Geode maintains multiple versions of each graph element. Readers access consistent snapshots without blocking writers, and writers don&rsquo;t block readers. This architecture delivers excellent concurrency while maintaining strict consistency.</p> <p><strong>Write-Ahead Logging (WAL)</strong>: Every change is first written to a durable log before being applied to the database. If the system crashes, Geode can recover to a consistent state by replaying the WAL.</p> <h3 id="transaction-lifecycle-in-geode" class="position-relative d-flex align-items-center group"> <span>Transaction Lifecycle in Geode</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="transaction-lifecycle-in-geode" aria-haspopup="dialog" aria-label="Share link: Transaction Lifecycle in Geode"> <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>Understanding the transaction lifecycle helps you write correct and efficient code:</p> <ol> <li><strong>BEGIN</strong>: Start a new transaction, creating a consistent snapshot of the database</li> <li><strong>EXECUTE</strong>: Run GQL queries and mutations within the transaction context</li> <li><strong>COMMIT</strong>: Persist all changes durably and make them visible to other transactions</li> <li><strong>ROLLBACK</strong>: Abort the transaction and discard all changes</li> </ol> <p>All database operations in Geode execute within a transaction context. If you don&rsquo;t explicitly begin a transaction, Geode automatically wraps each statement in its own implicit transaction.</p> <h3 id="using-transactions-in-gql" class="position-relative d-flex align-items-center group"> <span>Using Transactions in GQL</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="using-transactions-in-gql" aria-haspopup="dialog" aria-label="Share link: Using Transactions in GQL"> <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 provides standard SQL-style transaction control:</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">Explicit</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">START</span><span class="w"> </span><span class="py">TRANSACTION</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">Create</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">relationships</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">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</span><span class="p">})</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="py">p</span><span class="p">:</span><span class="nc">Post</span><span class="w"> </span><span class="p">{</span><span class="py">title</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">Post</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">content</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="kd">...</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="nc">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">POSTED</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">p</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></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">existing</span><span class="w"> </span><span class="py">data</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">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">456</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">u</span><span class="err">.</span><span class="py">last_login</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">current_timestamp</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></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Commit</span><span class="w"> </span><span class="py">all</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">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Rollback on Error</strong>:</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">START</span><span class="w"> </span><span class="py">TRANSACTION</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">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">account</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">account</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">account</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></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">account</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">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">account</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">account</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></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">anything</span><span class="w"> </span><span class="py">fails</span><span class="p">,</span><span class="w"> </span><span class="py">rollback</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><p><strong>Read-Only Transactions</strong>: Optimize read-heavy workloads by declaring transactions as read-only:</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">START</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">READ</span><span class="w"> </span><span class="py">ONLY</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">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">other</span><span class="p">:</span><span class="nc">User</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">u</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">collect</span><span class="p">(</span><span class="py">other</span><span class="err">.</span><span class="py">name</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></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="savepoints-for-complex-logic" class="position-relative d-flex align-items-center group"> <span>Savepoints for Complex Logic</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="savepoints-for-complex-logic" aria-haspopup="dialog" aria-label="Share link: Savepoints for Complex Logic"> <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>Savepoints enable partial rollback within a transaction, useful for implementing complex business logic:</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">START</span><span class="w"> </span><span class="py">TRANSACTION</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">Checkpoint</span><span class="w"> </span><span class="py">1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SAVEPOINT</span><span class="w"> </span><span class="py">before_user_update</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">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</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">u</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">New</span><span class="w"> </span><span class="py">Name</span><span class="err">&#39;;</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">Checkpoint</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">SAVEPOINT</span><span class="w"> </span><span class="py">before_post_creation</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">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Post</span><span class="w"> </span><span class="p">{</span><span class="py">title</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">Draft</span><span class="w"> </span><span class="py">Post</span><span class="err">&#39;</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></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Oops</span><span class="p">,</span><span class="w"> </span><span class="py">rollback</span><span class="w"> </span><span class="py">post</span><span class="w"> </span><span class="py">creation</span><span class="w"> </span><span class="py">but</span><span class="w"> </span><span class="py">keep</span><span class="w"> </span><span class="py">user</span><span class="w"> </span><span class="py">update</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ROLLBACK</span><span class="w"> </span><span class="py">TO</span><span class="w"> </span><span class="py">SAVEPOINT</span><span class="w"> </span><span class="py">before_post_creation</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">Release</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">savepoint</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RELEASE</span><span class="w"> </span><span class="py">SAVEPOINT</span><span class="w"> </span><span class="py">before_user_update</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>Savepoint Use Cases</strong>:</p> <ul> <li>Try-catch style error handling within transactions</li> <li>Implementing multi-step workflows with conditional logic</li> <li>Batch operations where some items may fail</li> <li>Testing changes before committing</li> </ul> <h3 id="transaction-isolation-and-concurrency" class="position-relative d-flex align-items-center group"> <span>Transaction Isolation and Concurrency</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="transaction-isolation-and-concurrency" aria-haspopup="dialog" aria-label="Share link: Transaction Isolation and Concurrency"> <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&rsquo;s SSI implementation prevents concurrency anomalies while maintaining high performance:</p> <p><strong>Preventing Lost Updates</strong>:</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></span><span class="line"><span class="cl"><span class="w"></span><span class="py">START</span><span class="w"> </span><span class="py">TRANSACTION</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">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</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">u</span><span class="err">.</span><span class="py">login_count</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">login_count</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 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="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">START</span><span class="w"> </span><span class="py">TRANSACTION</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">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</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">u</span><span class="err">.</span><span class="py">last_login</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">current_timestamp</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></code></pre></div><p>Both transactions succeed without conflict. MVCC ensures each sees a consistent snapshot and updates are properly serialized.</p> <p><strong>Detecting Write Conflicts</strong>:</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></span><span class="line"><span class="cl"><span class="w"></span><span class="py">START</span><span class="w"> </span><span class="py">TRANSACTION</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">Product</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">PROD</span><span class="err">-</span><span class="py">1</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">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">stock</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">0</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">stock</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">stock</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 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="p">(</span><span class="py">concurrent</span><span class="p">,</span><span class="w"> </span><span class="py">same</span><span class="w"> </span><span class="py">product</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">START</span><span class="w"> </span><span class="py">TRANSACTION</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">Product</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">PROD</span><span class="err">-</span><span class="py">1</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">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">stock</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">0</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">stock</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">stock</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 class="py">COMMIT</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">fail</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">serialization</span><span class="w"> </span><span class="py">error</span><span class="w"> </span></span></span></code></pre></div><p>If both transactions attempt to modify the same product concurrently, one will succeed and the other will be aborted with a serialization error. Your application should retry the failed transaction.</p> <h3 id="best-practices-for-transaction-management" class="position-relative d-flex align-items-center group"> <span>Best Practices for Transaction Management</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="best-practices-for-transaction-management" aria-haspopup="dialog" aria-label="Share link: Best Practices for Transaction Management"> <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><strong>Keep Transactions Short</strong>: Long-running transactions hold resources and increase conflict probability. Execute transactions quickly and commit as soon as possible.</p> <p><strong>Batch Operations Wisely</strong>: Group related operations into transactions, but avoid massive transactions that could exhaust memory:</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">Good</span><span class="p">:</span><span class="w"> </span><span class="nc">Reasonably</span><span class="w"> </span><span class="py">sized</span><span class="w"> </span><span class="py">batch</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">START</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="nv">$batch</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">item</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="py">n</span><span class="p">:</span><span class="nc">Node</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">item</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">data</span><span class="p">:</span><span class="w"> </span><span class="nc">item</span><span class="err">.</span><span class="py">data</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">Avoid</span><span class="p">:</span><span class="w"> </span><span class="nc">Extremely</span><span class="w"> </span><span class="py">large</span><span class="w"> </span><span class="py">batches</span><span class="w"> </span><span class="p">(</span><span class="err">&gt;</span><span class="py">100k</span><span class="w"> </span><span class="py">items</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">Instead</span><span class="p">,</span><span class="w"> </span><span class="py">split</span><span class="w"> </span><span class="py">into</span><span class="w"> </span><span class="py">multiple</span><span class="w"> </span><span class="py">transactions</span><span class="w"> </span></span></span></code></pre></div><p><strong>Use Read-Only Transactions</strong>: When you only need to query data, mark transactions as read-only for better performance and reduced conflict potential.</p> <p><strong>Handle Serialization Errors</strong>: SSI may abort transactions due to conflicts. Implement retry logic with exponential backoff:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">execute_with_retry</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">max_attempts</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_attempts</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="n">geode</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">SerializationError</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o">==</span> <span class="n">max_attempts</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">attempt</span><span class="p">))</span> </span></span></code></pre></div><p><strong>Avoid Mixing Reads and Writes</strong>: When possible, separate read-heavy and write-heavy operations. This reduces contention and improves throughput.</p> <p><strong>Use Savepoints for Complex Logic</strong>: Instead of aborting entire transactions, use savepoints to implement partial rollback logic.</p> <h3 id="transaction-performance-optimization" class="position-relative d-flex align-items-center group"> <span>Transaction Performance Optimization</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="transaction-performance-optimization" aria-haspopup="dialog" aria-label="Share link: Transaction Performance Optimization"> <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><strong>Connection Pooling</strong>: Reuse database connections to avoid transaction setup overhead:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode</span> <span class="kn">import</span> <span class="n">ConnectionPool</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">pool</span> <span class="o">=</span> <span class="n">ConnectionPool</span><span class="p">(</span><span class="n">max_connections</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">conn</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">get_connection</span><span class="p">()</span> </span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;START TRANSACTION&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="c1"># ... operations ...</span> </span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;COMMIT&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">pool</span><span class="o">.</span><span class="n">release</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span> </span></span></code></pre></div><p><strong>Prepared Statements</strong>: Pre-compile frequently used queries to reduce parsing overhead:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">stmt</span> <span class="o">=</span> <span class="n">geode</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {id: $user_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET u.last_login = current_timestamp() </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">with</span> <span class="n">geode</span><span class="o">.</span><span class="n">transaction</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">stmt</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">user_id</span><span class="o">=</span><span class="mi">123</span><span class="p">)</span> </span></span></code></pre></div><p><strong>Deferred Constraints</strong>: For bulk operations, consider deferring constraint checking until commit time to avoid intermediate validation overhead.</p> <p><strong>WAL Configuration</strong>: Tune WAL settings for your durability vs. performance requirements. Geode defaults to fsync on commit for maximum durability, but you can adjust for specific workloads.</p> <h3 id="distributed-transaction-coordination" class="position-relative d-flex align-items-center group"> <span>Distributed Transaction Coordination</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="distributed-transaction-coordination" aria-haspopup="dialog" aria-label="Share link: Distributed Transaction Coordination"> <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>For multi-node deployments, Geode coordinates distributed transactions:</p> <p><strong>Two-Phase Commit</strong>: Geode uses 2PC to ensure atomic commits across shards. The coordinator node ensures all participants commit or all abort.</p> <p><strong>Distributed Deadlock Detection</strong>: Geode detects deadlocks across nodes and aborts one transaction to resolve the deadlock.</p> <p><strong>Cross-Shard Transactions</strong>: Transactions can span multiple shards transparently:</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">START</span><span class="w"> </span><span class="py">TRANSACTION</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">May</span><span class="w"> </span><span class="py">access</span><span class="w"> </span><span class="py">data</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">different</span><span class="w"> </span><span class="py">shards</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">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</span><span class="p">}),</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">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">PROD</span><span class="err">-</span><span class="py">1</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">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">PURCHASED</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">p</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></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="monitoring-transaction-health" class="position-relative d-flex align-items-center group"> <span>Monitoring Transaction Health</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-transaction-health" aria-haspopup="dialog" aria-label="Share link: Monitoring Transaction Health"> <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>Monitor key transaction metrics to ensure system health:</p> <ul> <li><strong>Transaction throughput</strong>: Commits per second</li> <li><strong>Transaction latency</strong>: Time from START to COMMIT</li> <li><strong>Abort rate</strong>: Percentage of transactions rolled back</li> <li><strong>Conflict rate</strong>: Serialization failures per second</li> <li><strong>Long-running transactions</strong>: Identify transactions holding resources</li> </ul> <p>Use Geode&rsquo;s metrics endpoints to track these values:</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">View</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">statistics</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SHOW</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">STATS</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">Find</span><span class="w"> </span><span class="py">long</span><span class="err">-</span><span class="py">running</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">SHOW</span><span class="w"> </span><span class="py">TRANSACTIONS</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">duration</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">1000</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="troubleshooting-common-issues" class="position-relative d-flex align-items-center group"> <span>Troubleshooting Common Issues</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-common-issues" aria-haspopup="dialog" aria-label="Share link: Troubleshooting Common Issues"> <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><strong>High Abort Rates</strong>: If many transactions abort due to conflicts:</p> <ul> <li>Reduce transaction duration</li> <li>Decrease batch sizes</li> <li>Implement exponential backoff retry logic</li> <li>Consider partitioning hot data</li> </ul> <p><strong>Deadlocks</strong>: If deadlocks occur frequently:</p> <ul> <li>Access resources in consistent order across transactions</li> <li>Use shorter transactions</li> <li>Implement timeout logic</li> </ul> <p><strong>Performance Degradation</strong>: If transaction throughput drops:</p> <ul> <li>Check for long-running transactions blocking others</li> <li>Monitor WAL write performance</li> <li>Verify sufficient connection pool capacity</li> <li>Review query execution plans for inefficient operations</li> </ul> <h3 id="advanced-transaction-features" class="position-relative d-flex align-items-center group"> <span>Advanced Transaction Features</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="advanced-transaction-features" aria-haspopup="dialog" aria-label="Share link: Advanced Transaction Features"> <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><strong>Transaction Hooks</strong>: Register callbacks for transaction lifecycle events:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">on_commit</span><span class="p">(</span><span class="n">txn</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Trigger side effects after successful commit</span> </span></span><span class="line"><span class="cl"> <span class="n">send_notification</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">geode</span><span class="o">.</span><span class="n">register_hook</span><span class="p">(</span><span class="s1">&#39;after_commit&#39;</span><span class="p">,</span> <span class="n">on_commit</span><span class="p">)</span> </span></span></code></pre></div><p><strong>Deferred Triggers</strong>: Execute logic after transaction commit without blocking the commit path.</p> <p><strong>Read-Your-Writes Consistency</strong>: Geode guarantees that within a transaction, you always see your own writes, even before commit.</p> <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/acid/" >ACID Compliance and Guarantees</a> </li> <li><a href="/tags/mvcc/" >Multi-Version Concurrency Control (MVCC)</a> </li> <li><a href="/tags/ssi/" >Serializable Snapshot Isolation (SSI)</a> </li> <li><a href="/tags/wal/" >Write-Ahead Logging (WAL)</a> </li> <li><a href="/tags/concurrency/" >Concurrency Control</a> </li> <li><a href="/tags/performance/" >Performance Tuning and Optimization</a> </li> <li><a href="/tags/data-integrity/" >Data Integrity and Consistency</a> </li> </ul> <h3 id="transaction-isolation-levels-in-detail" class="position-relative d-flex align-items-center group"> <span>Transaction Isolation Levels in Detail</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="transaction-isolation-levels-in-detail" aria-haspopup="dialog" aria-label="Share link: Transaction Isolation Levels in Detail"> <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="serializable-snapshot-isolation-ssi" class="position-relative d-flex align-items-center group"> <span>Serializable Snapshot Isolation (SSI)</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-snapshot-isolation-ssi" aria-haspopup="dialog" aria-label="Share link: Serializable Snapshot Isolation (SSI)"> <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 default isolation level provides the strongest guarantees:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">ssi_example</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Default SSI behavior</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">result1</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN account.balance AS balance </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="s1">&#39;acc_123&#39;</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">balance</span> <span class="o">=</span> <span class="n">result1</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;balance&#34;</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span> <span class="k">if</span> <span class="n">result1</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Concurrent transaction cannot modify our snapshot</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">balance</span> <span class="o">&gt;=</span> <span class="mi">100</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance - 100 </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="s1">&#39;acc_123&#39;</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Commits only if no conflicts detected</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span></code></pre></div> <h4 id="read-committed-isolation" class="position-relative d-flex align-items-center group"> <span>Read Committed Isolation</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-isolation" aria-haspopup="dialog" aria-label="Share link: Read Committed Isolation"> <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>Lower isolation for higher concurrency:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">read_committed_example</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># If your deployment enables READ COMMITTED, the same flow applies</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">result1</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN product.stock AS stock </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;sku&#39;</span><span class="p">:</span> <span class="s1">&#39;PROD-123&#39;</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Another transaction commits here - you&#39;ll see the change</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">result2</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN product.stock AS stock </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;sku&#39;</span><span class="p">:</span> <span class="s1">&#39;PROD-123&#39;</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span></code></pre></div> <h3 id="advanced-transaction-patterns" class="position-relative d-flex align-items-center group"> <span>Advanced Transaction Patterns</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="advanced-transaction-patterns" aria-haspopup="dialog" aria-label="Share link: Advanced Transaction Patterns"> <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="two-phase-commit-for-distributed-transactions" class="position-relative d-flex align-items-center group"> <span>Two-Phase Commit for Distributed Transactions</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="two-phase-commit-for-distributed-transactions" aria-haspopup="dialog" aria-label="Share link: Two-Phase Commit for Distributed Transactions"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">DistributedTransaction</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">coordinator</span><span class="p">,</span> <span class="n">participants</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">coordinator</span> <span class="o">=</span> <span class="n">coordinator</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">participants</span> <span class="o">=</span> <span class="n">participants</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">transaction_id</span> <span class="o">=</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">operations</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute distributed transaction with 2PC.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">transaction_id</span> <span class="o">=</span> <span class="n">generate_tx_id</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Phase 1: Prepare</span> </span></span><span class="line"><span class="cl"> <span class="n">prepared</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">participant</span><span class="p">,</span> <span class="n">operation</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">participants</span><span class="p">,</span> <span class="n">operations</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">vote</span> <span class="o">=</span> <span class="k">await</span> <span class="n">participant</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">transaction_id</span><span class="p">,</span> <span class="n">operation</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">vote</span> <span class="o">!=</span> <span class="s1">&#39;PREPARED&#39;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">TransactionAbort</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Participant </span><span class="si">{</span><span class="n">participant</span><span class="si">}</span><span class="s2"> voted abort&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">prepared</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">participant</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Phase 2: Commit</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">participant</span> <span class="ow">in</span> <span class="n">prepared</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">participant</span><span class="o">.</span><span class="n">commit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">transaction_id</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">True</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Rollback all prepared participants</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">participant</span> <span class="ow">in</span> <span class="n">prepared</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">participant</span><span class="o">.</span><span class="n">rollback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">transaction_id</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Usage</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">distributed_transfer</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">coordinator</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s2">&#34;coordinator:3141&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">shard1</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s2">&#34;shard1:3141&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">shard2</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s2">&#34;shard2:3141&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">tx</span> <span class="o">=</span> <span class="n">DistributedTransaction</span><span class="p">(</span><span class="n">coordinator</span><span class="p">,</span> <span class="p">[</span><span class="n">shard1</span><span class="p">,</span> <span class="n">shard2</span><span class="p">])</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">operations</span> <span class="o">=</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Debit from account on shard1</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $from_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE account.balance &gt;= $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance - $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Credit to account on shard2</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $to_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance + $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">operations</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="saga-pattern-for-long-running-transactions" class="position-relative d-flex align-items-center group"> <span>Saga Pattern for Long-Running Transactions</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="saga-pattern-for-long-running-transactions" aria-haspopup="dialog" aria-label="Share link: Saga Pattern for Long-Running Transactions"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Saga</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Saga pattern for managing long-running business transactions.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">steps</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">compensations</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="nf">add_step</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">forward_action</span><span class="p">,</span> <span class="n">compensation_action</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">steps</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">forward_action</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">compensations</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">compensation_action</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute saga with automatic compensation on failure.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">completed_steps</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">step</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">steps</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">step</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">completed_steps</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">True</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Compensate in reverse order</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">completed_steps</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">compensations</span><span class="p">[</span><span class="n">i</span><span class="p">]()</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">comp_error</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Log compensation failure</span> </span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Compensation failed for step </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">comp_error</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Example: Order fulfillment saga</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">order_fulfillment_saga</span><span class="p">(</span><span class="n">order_id</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">saga</span> <span class="o">=</span> <span class="n">Saga</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 1: Reserve inventory</span> </span></span><span class="line"><span class="cl"> <span class="n">saga</span><span class="o">.</span><span class="n">add_step</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">forward_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE product.stock &gt;= $quantity </span></span></span><span class="line"><span class="cl"><span class="s2"> SET product.stock = product.stock - $quantity, </span></span></span><span class="line"><span class="cl"><span class="s2"> product.reserved = product.reserved + $quantity </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="n">order</span><span class="o">.</span><span class="n">items</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="n">compensation_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET product.stock = product.stock + $quantity, </span></span></span><span class="line"><span class="cl"><span class="s2"> product.reserved = product.reserved - $quantity </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="n">order</span><span class="o">.</span><span class="n">items</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 2: Process payment</span> </span></span><span class="line"><span class="cl"> <span class="n">saga</span><span class="o">.</span><span class="n">add_step</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">forward_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">process_payment</span><span class="p">(</span><span class="n">order</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="n">compensation_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">refund_payment</span><span class="p">(</span><span class="n">order</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Step 3: Create shipment</span> </span></span><span class="line"><span class="cl"> <span class="n">saga</span><span class="o">.</span><span class="n">add_step</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">forward_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">create_shipment</span><span class="p">(</span><span class="n">order</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="n">compensation_action</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">cancel_shipment</span><span class="p">(</span><span class="n">order</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">saga</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span> </span></span></code></pre></div> <h4 id="optimistic-locking-with-version-numbers" class="position-relative d-flex align-items-center group"> <span>Optimistic Locking with Version Numbers</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-locking-with-version-numbers" aria-haspopup="dialog" aria-label="Share link: Optimistic Locking with Version Numbers"> <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">Add</span><span class="w"> </span><span class="py">version</span><span class="w"> </span><span class="py">column</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">entities</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">product</span><span class="p">:</span><span class="nc">Product</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">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="p">,</span><span class="w"> </span><span class="py">0</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></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Optimistic</span><span class="w"> </span><span class="py">update</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">product</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">product</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">product</span><span class="err">.</span><span class="py">stock</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">stock</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nv">$quantity</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</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">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">new_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">If</span><span class="w"> </span><span class="py">version</span><span class="w"> </span><span class="py">mismatch</span><span class="p">,</span><span class="w"> </span><span class="py">handle</span><span class="w"> </span><span class="py">conflict</span><span class="w"> </span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">optimistic_update</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">sku</span><span class="p">,</span> <span class="n">quantity</span><span class="p">,</span> <span class="n">max_retries</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Update with optimistic locking and retry.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_retries</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Read current version</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN product.version AS version, product.stock AS stock </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;sku&#39;</span><span class="p">:</span> <span class="n">sku</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">row</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">ProductNotFound</span><span class="p">(</span><span class="n">sku</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">current_version</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;version&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">current_stock</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;stock&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">current_stock</span> <span class="o">&lt;</span> <span class="n">quantity</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">InsufficientStock</span><span class="p">(</span><span class="n">sku</span><span class="p">,</span> <span class="n">current_stock</span><span class="p">,</span> <span class="n">quantity</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Attempt update with version check</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">update_result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (product:Product {sku: $sku}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE product.version = $expected_version </span></span></span><span class="line"><span class="cl"><span class="s2"> SET product.stock = product.stock - $quantity, </span></span></span><span class="line"><span class="cl"><span class="s2"> product.version = product.version + 1 </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN product.version AS new_version </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;sku&#39;</span><span class="p">:</span> <span class="n">sku</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;expected_version&#39;</span><span class="p">:</span> <span class="n">current_version</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;quantity&#39;</span><span class="p">:</span> <span class="n">quantity</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">updated_row</span> <span class="o">=</span> <span class="n">update_result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">update_result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">updated_row</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">updated_row</span><span class="p">[</span><span class="s1">&#39;new_version&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Version mismatch - retry</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o">&lt;</span> <span class="n">max_retries</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">attempt</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="k">continue</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">OptimisticLockException</span><span class="p">(</span><span class="n">sku</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o">==</span> <span class="n">max_retries</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">attempt</span><span class="p">))</span> </span></span></code></pre></div> <h3 id="transaction-performance-tuning" class="position-relative d-flex align-items-center group"> <span>Transaction Performance Tuning</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="transaction-performance-tuning" aria-haspopup="dialog" aria-label="Share link: Transaction Performance Tuning"> <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="batch-operations-within-transactions" class="position-relative d-flex align-items-center group"> <span>Batch Operations Within Transactions</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="batch-operations-within-transactions" aria-haspopup="dialog" aria-label="Share link: Batch Operations Within Transactions"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">bulk_insert_with_batching</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">items</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">1000</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Insert large datasets efficiently using batched transactions.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">total_inserted</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">items</span><span class="p">),</span> <span class="n">batch_size</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">batch</span> <span class="o">=</span> <span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="n">batch_size</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $batch AS item </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (p:Product { </span></span></span><span class="line"><span class="cl"><span class="s2"> sku: item.sku, </span></span></span><span class="line"><span class="cl"><span class="s2"> name: item.name, </span></span></span><span class="line"><span class="cl"><span class="s2"> price: item.price, </span></span></span><span class="line"><span class="cl"><span class="s2"> created_at: datetime() </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;batch&#39;</span><span class="p">:</span> <span class="n">batch</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">total_inserted</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">batch</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Inserted </span><span class="si">{</span><span class="n">total_inserted</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">items</span><span class="p">)</span><span class="si">}</span><span class="s2"> items&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">total_inserted</span> </span></span></code></pre></div> <h4 id="connection-pooling-for-transaction-throughput" class="position-relative d-flex align-items-center group"> <span>Connection Pooling for Transaction Throughput</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="connection-pooling-for-transaction-throughput" aria-haspopup="dialog" aria-label="Share link: Connection Pooling for Transaction Throughput"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">ConnectionPool</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">TransactionPool</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">pool_size</span><span class="o">=</span><span class="mi">20</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span> <span class="o">=</span> <span class="n">ConnectionPool</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">port</span><span class="o">=</span><span class="n">port</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">min_connections</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">max_connections</span><span class="o">=</span><span class="n">pool_size</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">connection_timeout</span><span class="o">=</span><span class="mf">30.0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">idle_timeout</span><span class="o">=</span><span class="mf">300.0</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">execute_transaction</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">operations</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute transaction using pooled connection.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">conn</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">results</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">query</span><span class="p">,</span> <span class="n">params</span> <span class="ow">in</span> <span class="n">operations</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">])</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">results</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> <span class="k">finally</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="o">.</span><span class="n">release</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Usage</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">high_throughput_transactions</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">pool</span> <span class="o">=</span> <span class="n">TransactionPool</span><span class="p">(</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="mi">3141</span><span class="p">,</span> <span class="n">pool_size</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Execute 10000 concurrent transactions</span> </span></span><span class="line"><span class="cl"> <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10000</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">operations</span> <span class="o">=</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="s2">&#34;MATCH (u:User {id: $id}) SET u.last_seen = datetime()&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">i</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> <span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">task</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">execute_transaction</span><span class="p">(</span><span class="n">operations</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">tasks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">task</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">results</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Completed </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">results</span><span class="p">)</span><span class="si">}</span><span class="s2"> transactions&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="transaction-timeout-configuration" class="position-relative d-flex align-items-center group"> <span>Transaction Timeout 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="transaction-timeout-configuration" aria-haspopup="dialog" aria-label="Share link: Transaction Timeout 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> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">transaction_with_timeout</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">timeout_seconds</span><span class="o">=</span><span class="mi">30</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute transaction with explicit timeout.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">timeout_seconds</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Long-running operations</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET n.processed = true </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># More operations...</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Explicit rollback happens on exception</span> </span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Transaction exceeded </span><span class="si">{</span><span class="n">timeout_seconds</span><span class="si">}</span><span class="s2">s timeout&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span></code></pre></div> <h3 id="transaction-monitoring-and-debugging" class="position-relative d-flex align-items-center group"> <span>Transaction Monitoring and Debugging</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="transaction-monitoring-and-debugging" aria-haspopup="dialog" aria-label="Share link: Transaction Monitoring and Debugging"> <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="live-transaction-monitoring" class="position-relative d-flex align-items-center group"> <span>Live Transaction Monitoring</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="live-transaction-monitoring" aria-haspopup="dialog" aria-label="Share link: Live Transaction Monitoring"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">TransactionMonitor</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Monitor active transactions and identify issues.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">list_active_transactions</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;List all currently active transactions.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.list() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD transactionId, username, database, </span></span></span><span class="line"><span class="cl"><span class="s2"> elapsedTime, lockCount, status </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN transactionId, </span></span></span><span class="line"><span class="cl"><span class="s2"> username, </span></span></span><span class="line"><span class="cl"><span class="s2"> duration.inSeconds(elapsedTime) AS seconds, </span></span></span><span class="line"><span class="cl"><span class="s2"> lockCount, </span></span></span><span class="line"><span class="cl"><span class="s2"> status </span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY elapsedTime DESC </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">find_blocked_transactions</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Identify transactions waiting on locks.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.list() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD transactionId, status, waitingOn </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE status = &#39;BLOCKED&#39; </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN transactionId, waitingOn </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">kill_long_running_transaction</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tx_id</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Terminate a specific transaction.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.terminate($tx_id) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;tx_id&#39;</span><span class="p">:</span> <span class="n">tx_id</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Usage</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">monitor_transactions</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">monitor</span> <span class="o">=</span> <span class="n">TransactionMonitor</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Find long-running transactions</span> </span></span><span class="line"><span class="cl"> <span class="n">active</span> <span class="o">=</span> <span class="k">await</span> <span class="n">monitor</span><span class="o">.</span><span class="n">list_active_transactions</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">tx</span> <span class="ow">in</span> <span class="n">active</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">tx</span><span class="p">[</span><span class="s1">&#39;seconds&#39;</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">300</span><span class="p">:</span> <span class="c1"># 5 minutes</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Long-running tx: </span><span class="si">{</span><span class="n">tx</span><span class="p">[</span><span class="s1">&#39;transactionId&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="n">tx</span><span class="p">[</span><span class="s1">&#39;seconds&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">s)&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">monitor</span><span class="o">.</span><span class="n">kill_long_running_transaction</span><span class="p">(</span><span class="n">tx</span><span class="p">[</span><span class="s1">&#39;transactionId&#39;</span><span class="p">])</span> </span></span></code></pre></div> <h4 id="transaction-metrics-collection" class="position-relative d-flex align-items-center group"> <span>Transaction Metrics Collection</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="transaction-metrics-collection" aria-haspopup="dialog" aria-label="Share link: Transaction Metrics Collection"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">prometheus_client</span> <span class="kn">import</span> <span class="n">Counter</span><span class="p">,</span> <span class="n">Histogram</span><span class="p">,</span> <span class="n">Gauge</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Metrics</span> </span></span><span class="line"><span class="cl"><span class="n">transaction_total</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_transactions_total&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Total transactions&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">,</span> <span class="s1">&#39;isolation_level&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">transaction_duration</span> <span class="o">=</span> <span class="n">Histogram</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_transaction_duration_seconds&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Transaction execution time&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="s1">&#39;isolation_level&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="n">buckets</span><span class="o">=</span><span class="p">[</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">,</span> <span class="mf">10.0</span><span class="p">,</span> <span class="mf">30.0</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">active_transactions</span> <span class="o">=</span> <span class="n">Gauge</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_active_transactions&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Number of active transactions&#39;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">instrumented_transaction</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">operations</span><span class="p">,</span> <span class="n">isolation</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute transaction with metrics collection.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">active_transactions</span><span class="o">.</span><span class="n">inc</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">query</span><span class="p">,</span> <span class="n">params</span> <span class="ow">in</span> <span class="n">operations</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">duration</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start_time</span> </span></span><span class="line"><span class="cl"> <span class="n">transaction_total</span><span class="o">.</span><span class="n">labels</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status</span><span class="o">=</span><span class="s1">&#39;commit&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">isolation_level</span><span class="o">=</span><span class="n">isolation</span> <span class="ow">or</span> <span class="s1">&#39;serializable&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">.</span><span class="n">inc</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">transaction_duration</span><span class="o">.</span><span class="n">labels</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">isolation_level</span><span class="o">=</span><span class="n">isolation</span> <span class="ow">or</span> <span class="s1">&#39;serializable&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">.</span><span class="n">observe</span><span class="p">(</span><span class="n">duration</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">transaction_total</span><span class="o">.</span><span class="n">labels</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status</span><span class="o">=</span><span class="s1">&#39;rollback&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">isolation_level</span><span class="o">=</span><span class="n">isolation</span> <span class="ow">or</span> <span class="s1">&#39;serializable&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="o">.</span><span class="n">inc</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">finally</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">active_transactions</span><span class="o">.</span><span class="n">dec</span><span class="p">()</span> </span></span></code></pre></div> <h3 id="distributed-transaction-coordination-1" class="position-relative d-flex align-items-center group"> <span>Distributed Transaction Coordination</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="distributed-transaction-coordination-1" aria-haspopup="dialog" aria-label="Share link: Distributed Transaction Coordination"> <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="cross-shard-transaction-example" class="position-relative d-flex align-items-center group"> <span>Cross-Shard Transaction Example</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="cross-shard-transaction-example" aria-haspopup="dialog" aria-label="Share link: Cross-Shard Transaction Example"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">cross_shard_transfer</span><span class="p">(</span><span class="n">amount</span><span class="p">,</span> <span class="n">from_account</span><span class="p">,</span> <span class="n">to_account</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Transfer money across database shards.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Determine shards</span> </span></span><span class="line"><span class="cl"> <span class="n">from_shard</span> <span class="o">=</span> <span class="n">get_shard_for_account</span><span class="p">(</span><span class="n">from_account</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">to_shard</span> <span class="o">=</span> <span class="n">get_shard_for_account</span><span class="p">(</span><span class="n">to_account</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">from_shard</span> <span class="o">==</span> <span class="n">to_shard</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Same shard - simple transaction</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">from_shard</span><span class="o">.</span><span class="n">transaction</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">from_shard</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (from:Account {id: $from_id}), </span></span></span><span class="line"><span class="cl"><span class="s2"> (to:Account {id: $to_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE from.balance &gt;= $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> SET from.balance = from.balance - $amount, </span></span></span><span class="line"><span class="cl"><span class="s2"> to.balance = to.balance + $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;from_id&#39;</span><span class="p">:</span> <span class="n">from_account</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;to_id&#39;</span><span class="p">:</span> <span class="n">to_account</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;amount&#39;</span><span class="p">:</span> <span class="n">amount</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Cross-shard - distributed transaction</span> </span></span><span class="line"><span class="cl"> <span class="n">coordinator</span> <span class="o">=</span> <span class="n">DistributedTransactionCoordinator</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">coordinator</span><span class="o">.</span><span class="n">distributed_transaction</span><span class="p">([</span><span class="n">from_shard</span><span class="p">,</span> <span class="n">to_shard</span><span class="p">]):</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Debit from source shard</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">from_shard</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE account.balance &gt;= $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance - $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">from_account</span><span class="p">,</span> <span class="s1">&#39;amount&#39;</span><span class="p">:</span> <span class="n">amount</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Credit to destination shard</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">to_shard</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance + $amount </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">to_account</span><span class="p">,</span> <span class="s1">&#39;amount&#39;</span><span class="p">:</span> <span class="n">amount</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Coordinator ensures both commit or both rollback</span> </span></span></code></pre></div> <h3 id="troubleshooting-transaction-issues" class="position-relative d-flex align-items-center group"> <span>Troubleshooting Transaction Issues</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-transaction-issues" aria-haspopup="dialog" aria-label="Share link: Troubleshooting Transaction Issues"> <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="diagnosing-deadlocks" class="position-relative d-flex align-items-center group"> <span>Diagnosing 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="diagnosing-deadlocks" aria-haspopup="dialog" aria-label="Share link: Diagnosing 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><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">detect_deadlock_cycle</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Identify circular wait dependencies.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.graph() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD transaction, waitingFor </span></span></span><span class="line"><span class="cl"><span class="s2"> WITH collect({tx: transaction, waits: waitingFor}) AS dependencies </span></span></span><span class="line"><span class="cl"><span class="s2"> </span></span></span><span class="line"><span class="cl"><span class="s2"> // Find cycles </span></span></span><span class="line"><span class="cl"><span class="s2"> WITH dependencies </span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND dependencies AS d1 </span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND dependencies AS d2 </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE d1.tx = d2.waits AND d2.tx = d1.waits </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN DISTINCT d1.tx AS tx1, d2.tx AS tx2 </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">cycles</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">cycles</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Deadlock detected!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">cycle</span> <span class="ow">in</span> <span class="n">cycles</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; </span><span class="si">{</span><span class="n">cycle</span><span class="p">[</span><span class="s1">&#39;tx1&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> ↔ </span><span class="si">{</span><span class="n">cycle</span><span class="p">[</span><span class="s1">&#39;tx2&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">cycles</span> </span></span></code></pre></div> <h4 id="resolving-high-abort-rates" class="position-relative d-flex align-items-center group"> <span>Resolving High Abort Rates</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="resolving-high-abort-rates" aria-haspopup="dialog" aria-label="Share link: Resolving High Abort Rates"> <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-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">analyze_transaction_conflicts</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Analyze conflict patterns to reduce abort rate.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Identify hot spots (frequently conflicted entities)</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.conflicts.summary() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD entity, conflictCount, avgRetries </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE conflictCount &gt; 100 </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN entity, conflictCount, avgRetries </span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY conflictCount DESC </span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 20 </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">hotspots</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Recommendations</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">hotspot</span> <span class="ow">in</span> <span class="n">hotspots</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">entity</span> <span class="o">=</span> <span class="n">hotspot</span><span class="p">[</span><span class="s1">&#39;entity&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">conflicts</span> <span class="o">=</span> <span class="n">hotspot</span><span class="p">[</span><span class="s1">&#39;conflictCount&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">retries</span> <span class="o">=</span> <span class="n">hotspot</span><span class="p">[</span><span class="s1">&#39;avgRetries&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Hot spot: </span><span class="si">{</span><span class="n">entity</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Conflicts: </span><span class="si">{</span><span class="n">conflicts</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Avg retries: </span><span class="si">{</span><span class="n">retries</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Recommendation: Consider sharding or using queuing&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</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="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <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>ISO/IEC 39075:2024 GQL Transaction Semantics</li> <li>Transaction Processing: Concepts and Techniques</li> <li>Geode Architecture: MVCC Implementation</li> <li>Distributed Transaction Coordination</li> <li>Performance Tuning Guide</li> </ul>

Related Articles