[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-trigger-dev-staff-engineering-skills-race-conditions":3,"mdc--3jbzzh-key":34,"related-repo-trigger-dev-staff-engineering-skills-race-conditions":5370,"related-org-trigger-dev-staff-engineering-skills-race-conditions":5453},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"staff-engineering-skills-race-conditions","prevent race conditions in concurrent code","Detect and prevent race conditions in concurrent code. Use when writing code that reads then writes shared state, checks a condition then acts on it, creates records that should be unique, updates counters or balances, transitions status fields, or handles webhook\u002Fqueue retries. Activates on patterns like check-then-act, read-modify-write, findUnique-then-create, or any shared state mutation without atomicity guarantees.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"trigger-dev","Trigger.dev","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ftrigger-dev.jpg","triggerdotdev",[13,17,20],{"name":14,"slug":15,"type":16},"Architecture","architecture","tag",{"name":18,"slug":19,"type":16},"Engineering","engineering",{"name":21,"slug":22,"type":16},"Debugging","debugging",3,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fstaff-engineering-skills","2026-06-17T08:40:39.029905",null,1,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"Skills that give AI   coding agents staff-engineer instincts: recognizing and avoiding production failure modes like cardinality, idempotency, and race conditions.","https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fstaff-engineering-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fstaff-engineering-skills-race-conditions","---\nname: staff-engineering-skills-race-conditions\ndescription: Detect and prevent race conditions in concurrent code. Use when writing code that reads then writes shared state, checks a condition then acts on it, creates records that should be unique, updates counters or balances, transitions status fields, or handles webhook\u002Fqueue retries. Activates on patterns like check-then-act, read-modify-write, findUnique-then-create, or any shared state mutation without atomicity guarantees.\n---\n\n# Race Conditions Trap\n\nCode that reads correctly line by line can corrupt data when two copies run at once. Before writing any code that reads shared state and then writes based on what it read, ask: **what happens if another process changes the state between my read and my write?**\n\n## The Three Patterns\n\nAlmost every race condition is one of these:\n\n### 1. Check-Then-Act (TOCTOU)\n\nRead state, make a decision, act on it. Another process changes state between check and act.\n\n```typescript\n\u002F\u002F RACE: two requests both find no user, both create one\nconst existing = await db.user.findUnique({ where: { email } });\nif (!existing) return await db.user.create({ data: { email } });\n```\n\n### 2. Read-Modify-Write\n\nRead a value, compute a new value, write it back. Another process reads the same old value.\n\n```typescript\n\u002F\u002F RACE: two requests read inventory=1, both write inventory=0. Oversold by 1.\nconst product = await db.product.findUnique({ where: { id: productId } });\nif (product.inventory \u003C= 0) throw new Error(\"Out of stock\");\nawait db.product.update({ where: { id: productId }, data: { inventory: product.inventory - 1 } });\n```\n\n### 3. Check-Act-With-Side-Effects\n\nRead state, perform an irreversible action, update state. Another process reads the same state before update.\n\n```typescript\n\u002F\u002F RACE: two processes both see status=\"paid\", both ship the order\nconst order = await db.order.findUnique({ where: { id: orderId } });\nif (order.status !== \"paid\") throw new Error(\"Order not paid\");\nawait externalShippingApi.createShipment(order); \u002F\u002F irreversible!\nawait db.order.update({ where: { id: orderId }, data: { status: \"shipped\" } });\n```\n\n## Detection: When You're Writing a Race Condition\n\nStop and fix if you see any of these:\n\n1. **`findUnique`\u002F`findFirst` then `create`** -- classic check-then-act; two processes pass the check before either creates. Use a unique constraint + upsert or create-catch-conflict.\n2. **Read X, compute, write X back** (`X = X + 1`) -- use atomic ops (`{ increment: 1 }`, `UPDATE ... SET x = x + 1`).\n3. **Status read then updated in separate ops** (`if (status === \"A\") update(\"B\")`) -- use conditional WHERE `... SET status='B' WHERE status='A'` and check affected rows.\n4. **Any read-then-write to the same row without a transaction or atomic constraint** -- the gap between them is the race window.\n5. **Retry logic on non-idempotent operations** -- the first attempt may have succeeded with a lost response; the retry races the completed first attempt.\n6. **`if (!fs.existsSync(path)) fs.writeFileSync(path, data)`** -- filesystem TOCTOU; use `O_CREAT | O_EXCL`.\n\n## Fix: Let the Database Be the Arbiter\n\nThe database is the source of truth and the concurrency enforcer. Push race-prevention into the database layer, not application code.\n\n### Unique constraints (for check-then-act)\n\n```typescript\n\u002F\u002F SAFE: unique index on email. Only one create succeeds; loser falls back to find.\nasync function getOrCreateUser(email: string) {\n  try {\n    return await db.user.create({ data: { email } });\n  } catch (error) {\n    if (isPrismaUniqueConstraintError(error)) {\n      return await db.user.findUnique({ where: { email } });\n    }\n    throw error;\n  }\n}\n\n\u002F\u002F Or, if your ORM upserts atomically:\nconst user = await db.user.upsert({ where: { email }, create: { email, name }, update: {} });\n```\n\n### Atomic update with conditional WHERE (for read-modify-write)\n\n```typescript\n\u002F\u002F SAFE: decrement-and-check in one atomic statement (UPDATE ... SET inv = inv - 1 WHERE id = ? AND inv > 0)\nasync function decrementInventory(productId: string) {\n  const result = await db.product.updateMany({\n    where: { id: productId, inventory: { gt: 0 } },\n    data: { inventory: { decrement: 1 } },\n  });\n  if (result.count === 0) throw new Error(\"Out of stock\");\n}\n```\n\n### Conditional status transition (for state machines)\n\n```typescript\n\u002F\u002F SAFE: claim the transition atomically (UPDATE ... SET status='shipping' WHERE id=? AND status='paid') before any side effect\nasync function shipOrder(orderId: string) {\n  const result = await db.order.updateMany({\n    where: { id: orderId, status: \"paid\" },\n    data: { status: \"shipping\" }, \u002F\u002F claim it first\n  });\n  if (result.count === 0) throw new Error(\"Order not in paid state\");\n\n  await externalShippingApi.createShipment(orderId); \u002F\u002F now safe -- we own this transition\n  await db.order.update({ where: { id: orderId }, data: { status: \"shipped\" } });\n}\n```\n\n### Optimistic locking with version column\n\n```typescript\n\u002F\u002F SAFE: detects concurrent modification via version mismatch\nasync function updateDocument(docId: string, changes: Partial\u003CDoc>) {\n  const doc = await db.document.findUnique({ where: { id: docId } });\n  const result = await db.document.updateMany({\n    where: { id: docId, version: doc.version },\n    data: { ...changes, version: doc.version + 1 },\n  });\n  if (result.count === 0) throw new ConflictError(\"Document was modified by another process\");\n}\n```\n\n### Pessimistic locking (when you must hold state across external calls)\n\n```typescript\n\u002F\u002F SAFE: FOR UPDATE locks the row, serializing concurrent access\nasync function processPayment(orderId: string) {\n  await db.$transaction(async (tx) => {\n    const order = await tx.$queryRaw`SELECT * FROM orders WHERE id = ${orderId} FOR UPDATE`;\n    if (order.status !== \"pending\") throw new Error(\"Already processed\");\n\n    const charge = await stripe.charges.create({ amount: order.total });\n    await tx.order.update({\n      where: { id: orderId },\n      data: { status: \"paid\", stripeChargeId: charge.id },\n    });\n  });\n}\n```\n\nUse `SELECT FOR UPDATE` when you must read state, do external work (API calls), then write. Tradeoff: same-row operations serialize, reducing throughput.\n\n## Redis Atomic Operations\n\nRedis commands are single-threaded and atomic. Use them for fast, atomic operations on shared counters, flags, or sets that don't need database durability.\n\n### Atomic counter\n\n```typescript\n\u002F\u002F SAFE: DECR is atomic; incr to undo if we went negative\nasync function decrementInventory(productId: string) {\n  const remaining = await redis.decr(`inventory:${productId}`);\n  if (remaining \u003C 0) {\n    await redis.incr(`inventory:${productId}`);\n    throw new Error(\"Out of stock\");\n  }\n}\n```\n\n### Lua scripts for multi-step atomic operations\n\n```typescript\n\u002F\u002F SAFE: the whole script executes atomically in Redis\nconst CLAIM_COUPON = `\n  local used = redis.call('SISMEMBER', KEYS[1], ARGV[1])\n  if used == 1 then return 0 end\n  redis.call('SADD', KEYS[1], ARGV[1])\n  return 1\n`;\n\nasync function claimCoupon(couponId: string, userId: string): Promise\u003Cboolean> {\n  const result = await redis.eval(CLAIM_COUPON, 1, `coupon:${couponId}:used`, userId);\n  return result === 1;\n}\n```\n\n### SET NX for simple locks\n\n```typescript\n\u002F\u002F SAFE: atomic set-if-not-exists with auto-expiry to prevent deadlocks\nasync function acquireLock(resource: string, ttlMs: number): Promise\u003Cstring | null> {\n  const token = crypto.randomUUID();\n  const acquired = await redis.set(`lock:${resource}`, token, \"PX\", ttlMs, \"NX\");\n  return acquired === \"OK\" ? token : null;\n}\n\n\u002F\u002F Release with Lua so you only release YOUR lock\nconst RELEASE_LOCK = `\n  if redis.call('GET', KEYS[1]) == ARGV[1] then\n    return redis.call('DEL', KEYS[1])\n  end\n  return 0\n`;\n\nasync function releaseLock(resource: string, token: string) {\n  await redis.eval(RELEASE_LOCK, 1, `lock:${resource}`, token);\n}\n```\n\n## Distributed Locks and Redlock\n\nWhen you need mutual exclusion across processes or servers and `SELECT FOR UPDATE` won't work (e.g., the critical section touches non-database resources), you may need a distributed lock.\n\n**Single-instance Redis (usually sufficient):** `SET NX PX` (above) is good enough for most apps. Failure mode is well-understood: if Redis dies the lock is lost and two processes may enter the critical section. Acceptable when the lock is a best-effort guard, not a safety-critical mutex.\n\n**Redlock (when single-instance isn't enough):** uses N independent Redis instances (typically 5); a client holds the lock if it acquires a majority (N\u002F2 + 1) within a time bound.\n\n```typescript\nimport { Redlock } from \"redlock\";\n\nconst redlock = new Redlock([redis1, redis2, redis3, redis4, redis5], { retryCount: 3, retryDelay: 200 });\n\nasync function processExclusively(resourceId: string) {\n  const lock = await redlock.acquire([`lock:${resourceId}`], 30_000);\n  try {\n    await doExclusiveWork(resourceId);\n  } finally {\n    await lock.release();\n  }\n}\n```\n\n### When to use what\n\n| Approach | Use when | Tradeoff |\n|----------|----------|----------|\n| Database `SELECT FOR UPDATE` | Critical section is database operations | Serializes access, holds DB connection |\n| Single Redis `SET NX PX` | Best-effort mutual exclusion, single Redis | Lost on Redis failure |\n| Redlock (N Redis instances) | Need lock to survive single-node failure | Complex, clock-dependent, controversial |\n| Idempotency key | Operations can be safely retried | Doesn't prevent concurrent execution, just duplicate effects |\n\n**Redlock caveats:**\n- Depends on synchronized clocks; clock skew can let two processes both believe they hold the lock.\n- Kleppmann's \"How to do distributed locking\" argues it's unsafe for correctness-critical use. Add **fencing tokens** (monotonically increasing values downstream services validate) as a safety layer.\n- If the protected operation has side effects (API calls, charges), the lock alone isn't enough -- combine with idempotency keys.\n- Reach for Redlock only when you have a specific reason single-instance Redis isn't enough; otherwise a DB constraint or single Redis lock is simpler.\n\n## The Priority Order\n\nWhen fixing a race, prefer solutions in this order -- higher numbers mean more code, complexity, and failure modes:\n\n1. **Unique constraint** -- DB rejects duplicates, zero app code.\n2. **Atomic update** -- `SET x = x + 1 WHERE condition`, inherently atomic.\n3. **Upsert** -- `INSERT ... ON CONFLICT UPDATE`, atomic create-or-update.\n4. **Redis atomic ops** -- `DECR`, `SETNX`, Lua, for fast in-memory coordination.\n5. **Optimistic locking** -- version column in WHERE, retries on conflict.\n6. **Pessimistic locking** -- `SELECT FOR UPDATE`, blocks concurrent access.\n7. **Distributed lock (Redis\u002FRedlock)** -- cross-process mutual exclusion, last resort.\n\n## Anti-Patterns\n\n- **Check-then-act (TOCTOU)** -- `findUnique` then `create`, or \"check it doesn't exist, then insert.\" Two requests both pass the check and both write. Fix with a unique constraint.\n- **Read-modify-write in app code** -- read a counter or balance, compute the new value, write it back. Concurrent writers overwrite each other's increments. Fix with atomic `UPDATE ... SET x = x + n` or a version column.\n- **Acting on a stale status** -- read `status === \"pending\"`, then charge\u002Fship\u002Fsend. A retry reads the same status and acts twice. Gate the side effect on a conditional transition (`UPDATE ... WHERE status = 'pending'`) and check rows affected.\n- **Holding a distributed lock across an external call without a fence** -- the lock can expire mid-operation while a second worker acquires it. Carry a fencing token so stale holders are rejected.\n\n## Related Traps\n\n- **Idempotency** -- many races manifest as duplicate operations. If every operation is idempotent, races cause no harm. Idempotency keys are the primary defense against webhook and queue retry races.\n- **Consistency Models** -- replica lag creates races even in single-process code: you write to the primary, read from a replica, data isn't there yet. Read-after-write must hit the primary.\n- **Object Store as Database** -- S3 GET-modify-PUT without `If-Match` is a read-modify-write race. Use conditional writes for optimistic concurrency on object storage.\n",{"data":35,"body":36},{"name":4,"description":6},{"type":37,"children":38},"root",[39,48,60,67,72,79,84,305,311,316,628,634,639,975,981,986,1118,1124,1129,1135,1612,1618,1938,1944,2402,2408,2844,2850,3372,3385,3391,3396,3402,3662,3668,3963,3969,4507,4513,4525,4543,4553,4953,4959,5074,5082,5113,5119,5124,5232,5238,5317,5323,5364],{"type":40,"tag":41,"props":42,"children":44},"element","h1",{"id":43},"race-conditions-trap",[45],{"type":46,"value":47},"text","Race Conditions Trap",{"type":40,"tag":49,"props":50,"children":51},"p",{},[52,54],{"type":46,"value":53},"Code that reads correctly line by line can corrupt data when two copies run at once. Before writing any code that reads shared state and then writes based on what it read, ask: ",{"type":40,"tag":55,"props":56,"children":57},"strong",{},[58],{"type":46,"value":59},"what happens if another process changes the state between my read and my write?",{"type":40,"tag":61,"props":62,"children":64},"h2",{"id":63},"the-three-patterns",[65],{"type":46,"value":66},"The Three Patterns",{"type":40,"tag":49,"props":68,"children":69},{},[70],{"type":46,"value":71},"Almost every race condition is one of these:",{"type":40,"tag":73,"props":74,"children":76},"h3",{"id":75},"_1-check-then-act-toctou",[77],{"type":46,"value":78},"1. Check-Then-Act (TOCTOU)",{"type":40,"tag":49,"props":80,"children":81},{},[82],{"type":46,"value":83},"Read state, make a decision, act on it. Another process changes state between check and act.",{"type":40,"tag":85,"props":86,"children":91},"pre",{"className":87,"code":88,"language":89,"meta":90,"style":90},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F RACE: two requests both find no user, both create one\nconst existing = await db.user.findUnique({ where: { email } });\nif (!existing) return await db.user.create({ data: { email } });\n","typescript","",[92],{"type":40,"tag":93,"props":94,"children":95},"code",{"__ignoreMap":90},[96,107,211],{"type":40,"tag":97,"props":98,"children":100},"span",{"class":99,"line":27},"line",[101],{"type":40,"tag":97,"props":102,"children":104},{"style":103},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[105],{"type":46,"value":106},"\u002F\u002F RACE: two requests both find no user, both create one\n",{"type":40,"tag":97,"props":108,"children":110},{"class":99,"line":109},2,[111,117,123,129,135,140,145,150,154,160,165,170,176,181,186,191,196,201,206],{"type":40,"tag":97,"props":112,"children":114},{"style":113},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[115],{"type":46,"value":116},"const",{"type":40,"tag":97,"props":118,"children":120},{"style":119},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[121],{"type":46,"value":122}," existing ",{"type":40,"tag":97,"props":124,"children":126},{"style":125},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[127],{"type":46,"value":128},"=",{"type":40,"tag":97,"props":130,"children":132},{"style":131},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[133],{"type":46,"value":134}," await",{"type":40,"tag":97,"props":136,"children":137},{"style":119},[138],{"type":46,"value":139}," db",{"type":40,"tag":97,"props":141,"children":142},{"style":125},[143],{"type":46,"value":144},".",{"type":40,"tag":97,"props":146,"children":147},{"style":119},[148],{"type":46,"value":149},"user",{"type":40,"tag":97,"props":151,"children":152},{"style":125},[153],{"type":46,"value":144},{"type":40,"tag":97,"props":155,"children":157},{"style":156},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[158],{"type":46,"value":159},"findUnique",{"type":40,"tag":97,"props":161,"children":162},{"style":119},[163],{"type":46,"value":164},"(",{"type":40,"tag":97,"props":166,"children":167},{"style":125},[168],{"type":46,"value":169},"{",{"type":40,"tag":97,"props":171,"children":173},{"style":172},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[174],{"type":46,"value":175}," where",{"type":40,"tag":97,"props":177,"children":178},{"style":125},[179],{"type":46,"value":180},":",{"type":40,"tag":97,"props":182,"children":183},{"style":125},[184],{"type":46,"value":185}," {",{"type":40,"tag":97,"props":187,"children":188},{"style":119},[189],{"type":46,"value":190}," email ",{"type":40,"tag":97,"props":192,"children":193},{"style":125},[194],{"type":46,"value":195},"}",{"type":40,"tag":97,"props":197,"children":198},{"style":125},[199],{"type":46,"value":200}," }",{"type":40,"tag":97,"props":202,"children":203},{"style":119},[204],{"type":46,"value":205},")",{"type":40,"tag":97,"props":207,"children":208},{"style":125},[209],{"type":46,"value":210},";\n",{"type":40,"tag":97,"props":212,"children":213},{"class":99,"line":23},[214,219,224,229,234,239,243,247,251,255,259,264,268,272,277,281,285,289,293,297,301],{"type":40,"tag":97,"props":215,"children":216},{"style":131},[217],{"type":46,"value":218},"if",{"type":40,"tag":97,"props":220,"children":221},{"style":119},[222],{"type":46,"value":223}," (",{"type":40,"tag":97,"props":225,"children":226},{"style":125},[227],{"type":46,"value":228},"!",{"type":40,"tag":97,"props":230,"children":231},{"style":119},[232],{"type":46,"value":233},"existing) ",{"type":40,"tag":97,"props":235,"children":236},{"style":131},[237],{"type":46,"value":238},"return",{"type":40,"tag":97,"props":240,"children":241},{"style":131},[242],{"type":46,"value":134},{"type":40,"tag":97,"props":244,"children":245},{"style":119},[246],{"type":46,"value":139},{"type":40,"tag":97,"props":248,"children":249},{"style":125},[250],{"type":46,"value":144},{"type":40,"tag":97,"props":252,"children":253},{"style":119},[254],{"type":46,"value":149},{"type":40,"tag":97,"props":256,"children":257},{"style":125},[258],{"type":46,"value":144},{"type":40,"tag":97,"props":260,"children":261},{"style":156},[262],{"type":46,"value":263},"create",{"type":40,"tag":97,"props":265,"children":266},{"style":119},[267],{"type":46,"value":164},{"type":40,"tag":97,"props":269,"children":270},{"style":125},[271],{"type":46,"value":169},{"type":40,"tag":97,"props":273,"children":274},{"style":172},[275],{"type":46,"value":276}," data",{"type":40,"tag":97,"props":278,"children":279},{"style":125},[280],{"type":46,"value":180},{"type":40,"tag":97,"props":282,"children":283},{"style":125},[284],{"type":46,"value":185},{"type":40,"tag":97,"props":286,"children":287},{"style":119},[288],{"type":46,"value":190},{"type":40,"tag":97,"props":290,"children":291},{"style":125},[292],{"type":46,"value":195},{"type":40,"tag":97,"props":294,"children":295},{"style":125},[296],{"type":46,"value":200},{"type":40,"tag":97,"props":298,"children":299},{"style":119},[300],{"type":46,"value":205},{"type":40,"tag":97,"props":302,"children":303},{"style":125},[304],{"type":46,"value":210},{"type":40,"tag":73,"props":306,"children":308},{"id":307},"_2-read-modify-write",[309],{"type":46,"value":310},"2. Read-Modify-Write",{"type":40,"tag":49,"props":312,"children":313},{},[314],{"type":46,"value":315},"Read a value, compute a new value, write it back. Another process reads the same old value.",{"type":40,"tag":85,"props":317,"children":319},{"className":87,"code":318,"language":89,"meta":90,"style":90},"\u002F\u002F RACE: two requests read inventory=1, both write inventory=0. Oversold by 1.\nconst product = await db.product.findUnique({ where: { id: productId } });\nif (product.inventory \u003C= 0) throw new Error(\"Out of stock\");\nawait db.product.update({ where: { id: productId }, data: { inventory: product.inventory - 1 } });\n",[320],{"type":40,"tag":93,"props":321,"children":322},{"__ignoreMap":90},[323,331,422,501],{"type":40,"tag":97,"props":324,"children":325},{"class":99,"line":27},[326],{"type":40,"tag":97,"props":327,"children":328},{"style":103},[329],{"type":46,"value":330},"\u002F\u002F RACE: two requests read inventory=1, both write inventory=0. Oversold by 1.\n",{"type":40,"tag":97,"props":332,"children":333},{"class":99,"line":109},[334,338,343,347,351,355,359,364,368,372,376,380,384,388,392,397,401,406,410,414,418],{"type":40,"tag":97,"props":335,"children":336},{"style":113},[337],{"type":46,"value":116},{"type":40,"tag":97,"props":339,"children":340},{"style":119},[341],{"type":46,"value":342}," product ",{"type":40,"tag":97,"props":344,"children":345},{"style":125},[346],{"type":46,"value":128},{"type":40,"tag":97,"props":348,"children":349},{"style":131},[350],{"type":46,"value":134},{"type":40,"tag":97,"props":352,"children":353},{"style":119},[354],{"type":46,"value":139},{"type":40,"tag":97,"props":356,"children":357},{"style":125},[358],{"type":46,"value":144},{"type":40,"tag":97,"props":360,"children":361},{"style":119},[362],{"type":46,"value":363},"product",{"type":40,"tag":97,"props":365,"children":366},{"style":125},[367],{"type":46,"value":144},{"type":40,"tag":97,"props":369,"children":370},{"style":156},[371],{"type":46,"value":159},{"type":40,"tag":97,"props":373,"children":374},{"style":119},[375],{"type":46,"value":164},{"type":40,"tag":97,"props":377,"children":378},{"style":125},[379],{"type":46,"value":169},{"type":40,"tag":97,"props":381,"children":382},{"style":172},[383],{"type":46,"value":175},{"type":40,"tag":97,"props":385,"children":386},{"style":125},[387],{"type":46,"value":180},{"type":40,"tag":97,"props":389,"children":390},{"style":125},[391],{"type":46,"value":185},{"type":40,"tag":97,"props":393,"children":394},{"style":172},[395],{"type":46,"value":396}," id",{"type":40,"tag":97,"props":398,"children":399},{"style":125},[400],{"type":46,"value":180},{"type":40,"tag":97,"props":402,"children":403},{"style":119},[404],{"type":46,"value":405}," productId ",{"type":40,"tag":97,"props":407,"children":408},{"style":125},[409],{"type":46,"value":195},{"type":40,"tag":97,"props":411,"children":412},{"style":125},[413],{"type":46,"value":200},{"type":40,"tag":97,"props":415,"children":416},{"style":119},[417],{"type":46,"value":205},{"type":40,"tag":97,"props":419,"children":420},{"style":125},[421],{"type":46,"value":210},{"type":40,"tag":97,"props":423,"children":424},{"class":99,"line":23},[425,429,434,438,443,448,454,459,464,469,474,478,483,489,493,497],{"type":40,"tag":97,"props":426,"children":427},{"style":131},[428],{"type":46,"value":218},{"type":40,"tag":97,"props":430,"children":431},{"style":119},[432],{"type":46,"value":433}," (product",{"type":40,"tag":97,"props":435,"children":436},{"style":125},[437],{"type":46,"value":144},{"type":40,"tag":97,"props":439,"children":440},{"style":119},[441],{"type":46,"value":442},"inventory ",{"type":40,"tag":97,"props":444,"children":445},{"style":125},[446],{"type":46,"value":447},"\u003C=",{"type":40,"tag":97,"props":449,"children":451},{"style":450},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[452],{"type":46,"value":453}," 0",{"type":40,"tag":97,"props":455,"children":456},{"style":119},[457],{"type":46,"value":458},") ",{"type":40,"tag":97,"props":460,"children":461},{"style":131},[462],{"type":46,"value":463},"throw",{"type":40,"tag":97,"props":465,"children":466},{"style":125},[467],{"type":46,"value":468}," new",{"type":40,"tag":97,"props":470,"children":471},{"style":156},[472],{"type":46,"value":473}," Error",{"type":40,"tag":97,"props":475,"children":476},{"style":119},[477],{"type":46,"value":164},{"type":40,"tag":97,"props":479,"children":480},{"style":125},[481],{"type":46,"value":482},"\"",{"type":40,"tag":97,"props":484,"children":486},{"style":485},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[487],{"type":46,"value":488},"Out of stock",{"type":40,"tag":97,"props":490,"children":491},{"style":125},[492],{"type":46,"value":482},{"type":40,"tag":97,"props":494,"children":495},{"style":119},[496],{"type":46,"value":205},{"type":40,"tag":97,"props":498,"children":499},{"style":125},[500],{"type":46,"value":210},{"type":40,"tag":97,"props":502,"children":504},{"class":99,"line":503},4,[505,510,514,518,522,526,531,535,539,543,547,551,555,559,563,568,572,576,580,585,589,594,598,602,607,612,616,620,624],{"type":40,"tag":97,"props":506,"children":507},{"style":131},[508],{"type":46,"value":509},"await",{"type":40,"tag":97,"props":511,"children":512},{"style":119},[513],{"type":46,"value":139},{"type":40,"tag":97,"props":515,"children":516},{"style":125},[517],{"type":46,"value":144},{"type":40,"tag":97,"props":519,"children":520},{"style":119},[521],{"type":46,"value":363},{"type":40,"tag":97,"props":523,"children":524},{"style":125},[525],{"type":46,"value":144},{"type":40,"tag":97,"props":527,"children":528},{"style":156},[529],{"type":46,"value":530},"update",{"type":40,"tag":97,"props":532,"children":533},{"style":119},[534],{"type":46,"value":164},{"type":40,"tag":97,"props":536,"children":537},{"style":125},[538],{"type":46,"value":169},{"type":40,"tag":97,"props":540,"children":541},{"style":172},[542],{"type":46,"value":175},{"type":40,"tag":97,"props":544,"children":545},{"style":125},[546],{"type":46,"value":180},{"type":40,"tag":97,"props":548,"children":549},{"style":125},[550],{"type":46,"value":185},{"type":40,"tag":97,"props":552,"children":553},{"style":172},[554],{"type":46,"value":396},{"type":40,"tag":97,"props":556,"children":557},{"style":125},[558],{"type":46,"value":180},{"type":40,"tag":97,"props":560,"children":561},{"style":119},[562],{"type":46,"value":405},{"type":40,"tag":97,"props":564,"children":565},{"style":125},[566],{"type":46,"value":567},"},",{"type":40,"tag":97,"props":569,"children":570},{"style":172},[571],{"type":46,"value":276},{"type":40,"tag":97,"props":573,"children":574},{"style":125},[575],{"type":46,"value":180},{"type":40,"tag":97,"props":577,"children":578},{"style":125},[579],{"type":46,"value":185},{"type":40,"tag":97,"props":581,"children":582},{"style":172},[583],{"type":46,"value":584}," inventory",{"type":40,"tag":97,"props":586,"children":587},{"style":125},[588],{"type":46,"value":180},{"type":40,"tag":97,"props":590,"children":591},{"style":119},[592],{"type":46,"value":593}," product",{"type":40,"tag":97,"props":595,"children":596},{"style":125},[597],{"type":46,"value":144},{"type":40,"tag":97,"props":599,"children":600},{"style":119},[601],{"type":46,"value":442},{"type":40,"tag":97,"props":603,"children":604},{"style":125},[605],{"type":46,"value":606},"-",{"type":40,"tag":97,"props":608,"children":609},{"style":450},[610],{"type":46,"value":611}," 1",{"type":40,"tag":97,"props":613,"children":614},{"style":125},[615],{"type":46,"value":200},{"type":40,"tag":97,"props":617,"children":618},{"style":125},[619],{"type":46,"value":200},{"type":40,"tag":97,"props":621,"children":622},{"style":119},[623],{"type":46,"value":205},{"type":40,"tag":97,"props":625,"children":626},{"style":125},[627],{"type":46,"value":210},{"type":40,"tag":73,"props":629,"children":631},{"id":630},"_3-check-act-with-side-effects",[632],{"type":46,"value":633},"3. Check-Act-With-Side-Effects",{"type":40,"tag":49,"props":635,"children":636},{},[637],{"type":46,"value":638},"Read state, perform an irreversible action, update state. Another process reads the same state before update.",{"type":40,"tag":85,"props":640,"children":642},{"className":87,"code":641,"language":89,"meta":90,"style":90},"\u002F\u002F RACE: two processes both see status=\"paid\", both ship the order\nconst order = await db.order.findUnique({ where: { id: orderId } });\nif (order.status !== \"paid\") throw new Error(\"Order not paid\");\nawait externalShippingApi.createShipment(order); \u002F\u002F irreversible!\nawait db.order.update({ where: { id: orderId }, data: { status: \"shipped\" } });\n",[643],{"type":40,"tag":93,"props":644,"children":645},{"__ignoreMap":90},[646,654,744,825,861],{"type":40,"tag":97,"props":647,"children":648},{"class":99,"line":27},[649],{"type":40,"tag":97,"props":650,"children":651},{"style":103},[652],{"type":46,"value":653},"\u002F\u002F RACE: two processes both see status=\"paid\", both ship the order\n",{"type":40,"tag":97,"props":655,"children":656},{"class":99,"line":109},[657,661,666,670,674,678,682,687,691,695,699,703,707,711,715,719,723,728,732,736,740],{"type":40,"tag":97,"props":658,"children":659},{"style":113},[660],{"type":46,"value":116},{"type":40,"tag":97,"props":662,"children":663},{"style":119},[664],{"type":46,"value":665}," order ",{"type":40,"tag":97,"props":667,"children":668},{"style":125},[669],{"type":46,"value":128},{"type":40,"tag":97,"props":671,"children":672},{"style":131},[673],{"type":46,"value":134},{"type":40,"tag":97,"props":675,"children":676},{"style":119},[677],{"type":46,"value":139},{"type":40,"tag":97,"props":679,"children":680},{"style":125},[681],{"type":46,"value":144},{"type":40,"tag":97,"props":683,"children":684},{"style":119},[685],{"type":46,"value":686},"order",{"type":40,"tag":97,"props":688,"children":689},{"style":125},[690],{"type":46,"value":144},{"type":40,"tag":97,"props":692,"children":693},{"style":156},[694],{"type":46,"value":159},{"type":40,"tag":97,"props":696,"children":697},{"style":119},[698],{"type":46,"value":164},{"type":40,"tag":97,"props":700,"children":701},{"style":125},[702],{"type":46,"value":169},{"type":40,"tag":97,"props":704,"children":705},{"style":172},[706],{"type":46,"value":175},{"type":40,"tag":97,"props":708,"children":709},{"style":125},[710],{"type":46,"value":180},{"type":40,"tag":97,"props":712,"children":713},{"style":125},[714],{"type":46,"value":185},{"type":40,"tag":97,"props":716,"children":717},{"style":172},[718],{"type":46,"value":396},{"type":40,"tag":97,"props":720,"children":721},{"style":125},[722],{"type":46,"value":180},{"type":40,"tag":97,"props":724,"children":725},{"style":119},[726],{"type":46,"value":727}," orderId ",{"type":40,"tag":97,"props":729,"children":730},{"style":125},[731],{"type":46,"value":195},{"type":40,"tag":97,"props":733,"children":734},{"style":125},[735],{"type":46,"value":200},{"type":40,"tag":97,"props":737,"children":738},{"style":119},[739],{"type":46,"value":205},{"type":40,"tag":97,"props":741,"children":742},{"style":125},[743],{"type":46,"value":210},{"type":40,"tag":97,"props":745,"children":746},{"class":99,"line":23},[747,751,756,760,765,770,775,780,784,788,792,796,800,804,808,813,817,821],{"type":40,"tag":97,"props":748,"children":749},{"style":131},[750],{"type":46,"value":218},{"type":40,"tag":97,"props":752,"children":753},{"style":119},[754],{"type":46,"value":755}," (order",{"type":40,"tag":97,"props":757,"children":758},{"style":125},[759],{"type":46,"value":144},{"type":40,"tag":97,"props":761,"children":762},{"style":119},[763],{"type":46,"value":764},"status ",{"type":40,"tag":97,"props":766,"children":767},{"style":125},[768],{"type":46,"value":769},"!==",{"type":40,"tag":97,"props":771,"children":772},{"style":125},[773],{"type":46,"value":774}," \"",{"type":40,"tag":97,"props":776,"children":777},{"style":485},[778],{"type":46,"value":779},"paid",{"type":40,"tag":97,"props":781,"children":782},{"style":125},[783],{"type":46,"value":482},{"type":40,"tag":97,"props":785,"children":786},{"style":119},[787],{"type":46,"value":458},{"type":40,"tag":97,"props":789,"children":790},{"style":131},[791],{"type":46,"value":463},{"type":40,"tag":97,"props":793,"children":794},{"style":125},[795],{"type":46,"value":468},{"type":40,"tag":97,"props":797,"children":798},{"style":156},[799],{"type":46,"value":473},{"type":40,"tag":97,"props":801,"children":802},{"style":119},[803],{"type":46,"value":164},{"type":40,"tag":97,"props":805,"children":806},{"style":125},[807],{"type":46,"value":482},{"type":40,"tag":97,"props":809,"children":810},{"style":485},[811],{"type":46,"value":812},"Order not paid",{"type":40,"tag":97,"props":814,"children":815},{"style":125},[816],{"type":46,"value":482},{"type":40,"tag":97,"props":818,"children":819},{"style":119},[820],{"type":46,"value":205},{"type":40,"tag":97,"props":822,"children":823},{"style":125},[824],{"type":46,"value":210},{"type":40,"tag":97,"props":826,"children":827},{"class":99,"line":503},[828,832,837,841,846,851,856],{"type":40,"tag":97,"props":829,"children":830},{"style":131},[831],{"type":46,"value":509},{"type":40,"tag":97,"props":833,"children":834},{"style":119},[835],{"type":46,"value":836}," externalShippingApi",{"type":40,"tag":97,"props":838,"children":839},{"style":125},[840],{"type":46,"value":144},{"type":40,"tag":97,"props":842,"children":843},{"style":156},[844],{"type":46,"value":845},"createShipment",{"type":40,"tag":97,"props":847,"children":848},{"style":119},[849],{"type":46,"value":850},"(order)",{"type":40,"tag":97,"props":852,"children":853},{"style":125},[854],{"type":46,"value":855},";",{"type":40,"tag":97,"props":857,"children":858},{"style":103},[859],{"type":46,"value":860}," \u002F\u002F irreversible!\n",{"type":40,"tag":97,"props":862,"children":864},{"class":99,"line":863},5,[865,869,873,877,881,885,889,893,897,901,905,909,913,917,921,925,929,933,937,942,946,950,955,959,963,967,971],{"type":40,"tag":97,"props":866,"children":867},{"style":131},[868],{"type":46,"value":509},{"type":40,"tag":97,"props":870,"children":871},{"style":119},[872],{"type":46,"value":139},{"type":40,"tag":97,"props":874,"children":875},{"style":125},[876],{"type":46,"value":144},{"type":40,"tag":97,"props":878,"children":879},{"style":119},[880],{"type":46,"value":686},{"type":40,"tag":97,"props":882,"children":883},{"style":125},[884],{"type":46,"value":144},{"type":40,"tag":97,"props":886,"children":887},{"style":156},[888],{"type":46,"value":530},{"type":40,"tag":97,"props":890,"children":891},{"style":119},[892],{"type":46,"value":164},{"type":40,"tag":97,"props":894,"children":895},{"style":125},[896],{"type":46,"value":169},{"type":40,"tag":97,"props":898,"children":899},{"style":172},[900],{"type":46,"value":175},{"type":40,"tag":97,"props":902,"children":903},{"style":125},[904],{"type":46,"value":180},{"type":40,"tag":97,"props":906,"children":907},{"style":125},[908],{"type":46,"value":185},{"type":40,"tag":97,"props":910,"children":911},{"style":172},[912],{"type":46,"value":396},{"type":40,"tag":97,"props":914,"children":915},{"style":125},[916],{"type":46,"value":180},{"type":40,"tag":97,"props":918,"children":919},{"style":119},[920],{"type":46,"value":727},{"type":40,"tag":97,"props":922,"children":923},{"style":125},[924],{"type":46,"value":567},{"type":40,"tag":97,"props":926,"children":927},{"style":172},[928],{"type":46,"value":276},{"type":40,"tag":97,"props":930,"children":931},{"style":125},[932],{"type":46,"value":180},{"type":40,"tag":97,"props":934,"children":935},{"style":125},[936],{"type":46,"value":185},{"type":40,"tag":97,"props":938,"children":939},{"style":172},[940],{"type":46,"value":941}," status",{"type":40,"tag":97,"props":943,"children":944},{"style":125},[945],{"type":46,"value":180},{"type":40,"tag":97,"props":947,"children":948},{"style":125},[949],{"type":46,"value":774},{"type":40,"tag":97,"props":951,"children":952},{"style":485},[953],{"type":46,"value":954},"shipped",{"type":40,"tag":97,"props":956,"children":957},{"style":125},[958],{"type":46,"value":482},{"type":40,"tag":97,"props":960,"children":961},{"style":125},[962],{"type":46,"value":200},{"type":40,"tag":97,"props":964,"children":965},{"style":125},[966],{"type":46,"value":200},{"type":40,"tag":97,"props":968,"children":969},{"style":119},[970],{"type":46,"value":205},{"type":40,"tag":97,"props":972,"children":973},{"style":125},[974],{"type":46,"value":210},{"type":40,"tag":61,"props":976,"children":978},{"id":977},"detection-when-youre-writing-a-race-condition",[979],{"type":46,"value":980},"Detection: When You're Writing a Race Condition",{"type":40,"tag":49,"props":982,"children":983},{},[984],{"type":46,"value":985},"Stop and fix if you see any of these:",{"type":40,"tag":987,"props":988,"children":989},"ol",{},[990,1019,1052,1077,1087,1097],{"type":40,"tag":991,"props":992,"children":993},"li",{},[994,1017],{"type":40,"tag":55,"props":995,"children":996},{},[997,1002,1004,1010,1012],{"type":40,"tag":93,"props":998,"children":1000},{"className":999},[],[1001],{"type":46,"value":159},{"type":46,"value":1003},"\u002F",{"type":40,"tag":93,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":46,"value":1009},"findFirst",{"type":46,"value":1011}," then ",{"type":40,"tag":93,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":46,"value":263},{"type":46,"value":1018}," -- classic check-then-act; two processes pass the check before either creates. Use a unique constraint + upsert or create-catch-conflict.",{"type":40,"tag":991,"props":1020,"children":1021},{},[1022,1027,1028,1034,1036,1042,1044,1050],{"type":40,"tag":55,"props":1023,"children":1024},{},[1025],{"type":46,"value":1026},"Read X, compute, write X back",{"type":46,"value":223},{"type":40,"tag":93,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":46,"value":1033},"X = X + 1",{"type":46,"value":1035},") -- use atomic ops (",{"type":40,"tag":93,"props":1037,"children":1039},{"className":1038},[],[1040],{"type":46,"value":1041},"{ increment: 1 }",{"type":46,"value":1043},", ",{"type":40,"tag":93,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":46,"value":1049},"UPDATE ... SET x = x + 1",{"type":46,"value":1051},").",{"type":40,"tag":991,"props":1053,"children":1054},{},[1055,1060,1061,1067,1069,1075],{"type":40,"tag":55,"props":1056,"children":1057},{},[1058],{"type":46,"value":1059},"Status read then updated in separate ops",{"type":46,"value":223},{"type":40,"tag":93,"props":1062,"children":1064},{"className":1063},[],[1065],{"type":46,"value":1066},"if (status === \"A\") update(\"B\")",{"type":46,"value":1068},") -- use conditional WHERE ",{"type":40,"tag":93,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":46,"value":1074},"... SET status='B' WHERE status='A'",{"type":46,"value":1076}," and check affected rows.",{"type":40,"tag":991,"props":1078,"children":1079},{},[1080,1085],{"type":40,"tag":55,"props":1081,"children":1082},{},[1083],{"type":46,"value":1084},"Any read-then-write to the same row without a transaction or atomic constraint",{"type":46,"value":1086}," -- the gap between them is the race window.",{"type":40,"tag":991,"props":1088,"children":1089},{},[1090,1095],{"type":40,"tag":55,"props":1091,"children":1092},{},[1093],{"type":46,"value":1094},"Retry logic on non-idempotent operations",{"type":46,"value":1096}," -- the first attempt may have succeeded with a lost response; the retry races the completed first attempt.",{"type":40,"tag":991,"props":1098,"children":1099},{},[1100,1109,1111,1117],{"type":40,"tag":55,"props":1101,"children":1102},{},[1103],{"type":40,"tag":93,"props":1104,"children":1106},{"className":1105},[],[1107],{"type":46,"value":1108},"if (!fs.existsSync(path)) fs.writeFileSync(path, data)",{"type":46,"value":1110}," -- filesystem TOCTOU; use ",{"type":40,"tag":93,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":46,"value":1116},"O_CREAT | O_EXCL",{"type":46,"value":144},{"type":40,"tag":61,"props":1119,"children":1121},{"id":1120},"fix-let-the-database-be-the-arbiter",[1122],{"type":46,"value":1123},"Fix: Let the Database Be the Arbiter",{"type":40,"tag":49,"props":1125,"children":1126},{},[1127],{"type":46,"value":1128},"The database is the source of truth and the concurrency enforcer. Push race-prevention into the database layer, not application code.",{"type":40,"tag":73,"props":1130,"children":1132},{"id":1131},"unique-constraints-for-check-then-act",[1133],{"type":46,"value":1134},"Unique constraints (for check-then-act)",{"type":40,"tag":85,"props":1136,"children":1138},{"className":87,"code":1137,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: unique index on email. Only one create succeeds; loser falls back to find.\nasync function getOrCreateUser(email: string) {\n  try {\n    return await db.user.create({ data: { email } });\n  } catch (error) {\n    if (isPrismaUniqueConstraintError(error)) {\n      return await db.user.findUnique({ where: { email } });\n    }\n    throw error;\n  }\n}\n\n\u002F\u002F Or, if your ORM upserts atomically:\nconst user = await db.user.upsert({ where: { email }, create: { email, name }, update: {} });\n",[1139],{"type":40,"tag":93,"props":1140,"children":1141},{"__ignoreMap":90},[1142,1150,1197,1209,1282,1313,1348,1421,1430,1448,1457,1466,1476,1485],{"type":40,"tag":97,"props":1143,"children":1144},{"class":99,"line":27},[1145],{"type":40,"tag":97,"props":1146,"children":1147},{"style":103},[1148],{"type":46,"value":1149},"\u002F\u002F SAFE: unique index on email. Only one create succeeds; loser falls back to find.\n",{"type":40,"tag":97,"props":1151,"children":1152},{"class":99,"line":109},[1153,1158,1163,1168,1172,1178,1182,1188,1192],{"type":40,"tag":97,"props":1154,"children":1155},{"style":113},[1156],{"type":46,"value":1157},"async",{"type":40,"tag":97,"props":1159,"children":1160},{"style":113},[1161],{"type":46,"value":1162}," function",{"type":40,"tag":97,"props":1164,"children":1165},{"style":156},[1166],{"type":46,"value":1167}," getOrCreateUser",{"type":40,"tag":97,"props":1169,"children":1170},{"style":125},[1171],{"type":46,"value":164},{"type":40,"tag":97,"props":1173,"children":1175},{"style":1174},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[1176],{"type":46,"value":1177},"email",{"type":40,"tag":97,"props":1179,"children":1180},{"style":125},[1181],{"type":46,"value":180},{"type":40,"tag":97,"props":1183,"children":1185},{"style":1184},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[1186],{"type":46,"value":1187}," string",{"type":40,"tag":97,"props":1189,"children":1190},{"style":125},[1191],{"type":46,"value":205},{"type":40,"tag":97,"props":1193,"children":1194},{"style":125},[1195],{"type":46,"value":1196}," {\n",{"type":40,"tag":97,"props":1198,"children":1199},{"class":99,"line":23},[1200,1205],{"type":40,"tag":97,"props":1201,"children":1202},{"style":131},[1203],{"type":46,"value":1204},"  try",{"type":40,"tag":97,"props":1206,"children":1207},{"style":125},[1208],{"type":46,"value":1196},{"type":40,"tag":97,"props":1210,"children":1211},{"class":99,"line":503},[1212,1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1266,1270,1274,1278],{"type":40,"tag":97,"props":1213,"children":1214},{"style":131},[1215],{"type":46,"value":1216},"    return",{"type":40,"tag":97,"props":1218,"children":1219},{"style":131},[1220],{"type":46,"value":134},{"type":40,"tag":97,"props":1222,"children":1223},{"style":119},[1224],{"type":46,"value":139},{"type":40,"tag":97,"props":1226,"children":1227},{"style":125},[1228],{"type":46,"value":144},{"type":40,"tag":97,"props":1230,"children":1231},{"style":119},[1232],{"type":46,"value":149},{"type":40,"tag":97,"props":1234,"children":1235},{"style":125},[1236],{"type":46,"value":144},{"type":40,"tag":97,"props":1238,"children":1239},{"style":156},[1240],{"type":46,"value":263},{"type":40,"tag":97,"props":1242,"children":1243},{"style":172},[1244],{"type":46,"value":164},{"type":40,"tag":97,"props":1246,"children":1247},{"style":125},[1248],{"type":46,"value":169},{"type":40,"tag":97,"props":1250,"children":1251},{"style":172},[1252],{"type":46,"value":276},{"type":40,"tag":97,"props":1254,"children":1255},{"style":125},[1256],{"type":46,"value":180},{"type":40,"tag":97,"props":1258,"children":1259},{"style":125},[1260],{"type":46,"value":185},{"type":40,"tag":97,"props":1262,"children":1263},{"style":119},[1264],{"type":46,"value":1265}," email",{"type":40,"tag":97,"props":1267,"children":1268},{"style":125},[1269],{"type":46,"value":200},{"type":40,"tag":97,"props":1271,"children":1272},{"style":125},[1273],{"type":46,"value":200},{"type":40,"tag":97,"props":1275,"children":1276},{"style":172},[1277],{"type":46,"value":205},{"type":40,"tag":97,"props":1279,"children":1280},{"style":125},[1281],{"type":46,"value":210},{"type":40,"tag":97,"props":1283,"children":1284},{"class":99,"line":863},[1285,1290,1295,1299,1304,1308],{"type":40,"tag":97,"props":1286,"children":1287},{"style":125},[1288],{"type":46,"value":1289},"  }",{"type":40,"tag":97,"props":1291,"children":1292},{"style":131},[1293],{"type":46,"value":1294}," catch",{"type":40,"tag":97,"props":1296,"children":1297},{"style":172},[1298],{"type":46,"value":223},{"type":40,"tag":97,"props":1300,"children":1301},{"style":119},[1302],{"type":46,"value":1303},"error",{"type":40,"tag":97,"props":1305,"children":1306},{"style":172},[1307],{"type":46,"value":458},{"type":40,"tag":97,"props":1309,"children":1310},{"style":125},[1311],{"type":46,"value":1312},"{\n",{"type":40,"tag":97,"props":1314,"children":1316},{"class":99,"line":1315},6,[1317,1322,1326,1331,1335,1339,1344],{"type":40,"tag":97,"props":1318,"children":1319},{"style":131},[1320],{"type":46,"value":1321},"    if",{"type":40,"tag":97,"props":1323,"children":1324},{"style":172},[1325],{"type":46,"value":223},{"type":40,"tag":97,"props":1327,"children":1328},{"style":156},[1329],{"type":46,"value":1330},"isPrismaUniqueConstraintError",{"type":40,"tag":97,"props":1332,"children":1333},{"style":172},[1334],{"type":46,"value":164},{"type":40,"tag":97,"props":1336,"children":1337},{"style":119},[1338],{"type":46,"value":1303},{"type":40,"tag":97,"props":1340,"children":1341},{"style":172},[1342],{"type":46,"value":1343},")) ",{"type":40,"tag":97,"props":1345,"children":1346},{"style":125},[1347],{"type":46,"value":1312},{"type":40,"tag":97,"props":1349,"children":1351},{"class":99,"line":1350},7,[1352,1357,1361,1365,1369,1373,1377,1381,1385,1389,1393,1397,1401,1405,1409,1413,1417],{"type":40,"tag":97,"props":1353,"children":1354},{"style":131},[1355],{"type":46,"value":1356},"      return",{"type":40,"tag":97,"props":1358,"children":1359},{"style":131},[1360],{"type":46,"value":134},{"type":40,"tag":97,"props":1362,"children":1363},{"style":119},[1364],{"type":46,"value":139},{"type":40,"tag":97,"props":1366,"children":1367},{"style":125},[1368],{"type":46,"value":144},{"type":40,"tag":97,"props":1370,"children":1371},{"style":119},[1372],{"type":46,"value":149},{"type":40,"tag":97,"props":1374,"children":1375},{"style":125},[1376],{"type":46,"value":144},{"type":40,"tag":97,"props":1378,"children":1379},{"style":156},[1380],{"type":46,"value":159},{"type":40,"tag":97,"props":1382,"children":1383},{"style":172},[1384],{"type":46,"value":164},{"type":40,"tag":97,"props":1386,"children":1387},{"style":125},[1388],{"type":46,"value":169},{"type":40,"tag":97,"props":1390,"children":1391},{"style":172},[1392],{"type":46,"value":175},{"type":40,"tag":97,"props":1394,"children":1395},{"style":125},[1396],{"type":46,"value":180},{"type":40,"tag":97,"props":1398,"children":1399},{"style":125},[1400],{"type":46,"value":185},{"type":40,"tag":97,"props":1402,"children":1403},{"style":119},[1404],{"type":46,"value":1265},{"type":40,"tag":97,"props":1406,"children":1407},{"style":125},[1408],{"type":46,"value":200},{"type":40,"tag":97,"props":1410,"children":1411},{"style":125},[1412],{"type":46,"value":200},{"type":40,"tag":97,"props":1414,"children":1415},{"style":172},[1416],{"type":46,"value":205},{"type":40,"tag":97,"props":1418,"children":1419},{"style":125},[1420],{"type":46,"value":210},{"type":40,"tag":97,"props":1422,"children":1424},{"class":99,"line":1423},8,[1425],{"type":40,"tag":97,"props":1426,"children":1427},{"style":125},[1428],{"type":46,"value":1429},"    }\n",{"type":40,"tag":97,"props":1431,"children":1433},{"class":99,"line":1432},9,[1434,1439,1444],{"type":40,"tag":97,"props":1435,"children":1436},{"style":131},[1437],{"type":46,"value":1438},"    throw",{"type":40,"tag":97,"props":1440,"children":1441},{"style":119},[1442],{"type":46,"value":1443}," error",{"type":40,"tag":97,"props":1445,"children":1446},{"style":125},[1447],{"type":46,"value":210},{"type":40,"tag":97,"props":1449,"children":1451},{"class":99,"line":1450},10,[1452],{"type":40,"tag":97,"props":1453,"children":1454},{"style":125},[1455],{"type":46,"value":1456},"  }\n",{"type":40,"tag":97,"props":1458,"children":1460},{"class":99,"line":1459},11,[1461],{"type":40,"tag":97,"props":1462,"children":1463},{"style":125},[1464],{"type":46,"value":1465},"}\n",{"type":40,"tag":97,"props":1467,"children":1469},{"class":99,"line":1468},12,[1470],{"type":40,"tag":97,"props":1471,"children":1473},{"emptyLinePlaceholder":1472},true,[1474],{"type":46,"value":1475},"\n",{"type":40,"tag":97,"props":1477,"children":1479},{"class":99,"line":1478},13,[1480],{"type":40,"tag":97,"props":1481,"children":1482},{"style":103},[1483],{"type":46,"value":1484},"\u002F\u002F Or, if your ORM upserts atomically:\n",{"type":40,"tag":97,"props":1486,"children":1488},{"class":99,"line":1487},14,[1489,1493,1498,1502,1506,1510,1514,1518,1522,1527,1531,1535,1539,1543,1547,1551,1555,1560,1564,1568,1572,1577,1582,1586,1591,1595,1600,1604,1608],{"type":40,"tag":97,"props":1490,"children":1491},{"style":113},[1492],{"type":46,"value":116},{"type":40,"tag":97,"props":1494,"children":1495},{"style":119},[1496],{"type":46,"value":1497}," user ",{"type":40,"tag":97,"props":1499,"children":1500},{"style":125},[1501],{"type":46,"value":128},{"type":40,"tag":97,"props":1503,"children":1504},{"style":131},[1505],{"type":46,"value":134},{"type":40,"tag":97,"props":1507,"children":1508},{"style":119},[1509],{"type":46,"value":139},{"type":40,"tag":97,"props":1511,"children":1512},{"style":125},[1513],{"type":46,"value":144},{"type":40,"tag":97,"props":1515,"children":1516},{"style":119},[1517],{"type":46,"value":149},{"type":40,"tag":97,"props":1519,"children":1520},{"style":125},[1521],{"type":46,"value":144},{"type":40,"tag":97,"props":1523,"children":1524},{"style":156},[1525],{"type":46,"value":1526},"upsert",{"type":40,"tag":97,"props":1528,"children":1529},{"style":119},[1530],{"type":46,"value":164},{"type":40,"tag":97,"props":1532,"children":1533},{"style":125},[1534],{"type":46,"value":169},{"type":40,"tag":97,"props":1536,"children":1537},{"style":172},[1538],{"type":46,"value":175},{"type":40,"tag":97,"props":1540,"children":1541},{"style":125},[1542],{"type":46,"value":180},{"type":40,"tag":97,"props":1544,"children":1545},{"style":125},[1546],{"type":46,"value":185},{"type":40,"tag":97,"props":1548,"children":1549},{"style":119},[1550],{"type":46,"value":190},{"type":40,"tag":97,"props":1552,"children":1553},{"style":125},[1554],{"type":46,"value":567},{"type":40,"tag":97,"props":1556,"children":1557},{"style":172},[1558],{"type":46,"value":1559}," create",{"type":40,"tag":97,"props":1561,"children":1562},{"style":125},[1563],{"type":46,"value":180},{"type":40,"tag":97,"props":1565,"children":1566},{"style":125},[1567],{"type":46,"value":185},{"type":40,"tag":97,"props":1569,"children":1570},{"style":119},[1571],{"type":46,"value":1265},{"type":40,"tag":97,"props":1573,"children":1574},{"style":125},[1575],{"type":46,"value":1576},",",{"type":40,"tag":97,"props":1578,"children":1579},{"style":119},[1580],{"type":46,"value":1581}," name ",{"type":40,"tag":97,"props":1583,"children":1584},{"style":125},[1585],{"type":46,"value":567},{"type":40,"tag":97,"props":1587,"children":1588},{"style":172},[1589],{"type":46,"value":1590}," update",{"type":40,"tag":97,"props":1592,"children":1593},{"style":125},[1594],{"type":46,"value":180},{"type":40,"tag":97,"props":1596,"children":1597},{"style":125},[1598],{"type":46,"value":1599}," {}",{"type":40,"tag":97,"props":1601,"children":1602},{"style":125},[1603],{"type":46,"value":200},{"type":40,"tag":97,"props":1605,"children":1606},{"style":119},[1607],{"type":46,"value":205},{"type":40,"tag":97,"props":1609,"children":1610},{"style":125},[1611],{"type":46,"value":210},{"type":40,"tag":73,"props":1613,"children":1615},{"id":1614},"atomic-update-with-conditional-where-for-read-modify-write",[1616],{"type":46,"value":1617},"Atomic update with conditional WHERE (for read-modify-write)",{"type":40,"tag":85,"props":1619,"children":1621},{"className":87,"code":1620,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: decrement-and-check in one atomic statement (UPDATE ... SET inv = inv - 1 WHERE id = ? AND inv > 0)\nasync function decrementInventory(productId: string) {\n  const result = await db.product.updateMany({\n    where: { id: productId, inventory: { gt: 0 } },\n    data: { inventory: { decrement: 1 } },\n  });\n  if (result.count === 0) throw new Error(\"Out of stock\");\n}\n",[1622],{"type":40,"tag":93,"props":1623,"children":1624},{"__ignoreMap":90},[1625,1633,1674,1725,1792,1841,1856,1931],{"type":40,"tag":97,"props":1626,"children":1627},{"class":99,"line":27},[1628],{"type":40,"tag":97,"props":1629,"children":1630},{"style":103},[1631],{"type":46,"value":1632},"\u002F\u002F SAFE: decrement-and-check in one atomic statement (UPDATE ... SET inv = inv - 1 WHERE id = ? AND inv > 0)\n",{"type":40,"tag":97,"props":1634,"children":1635},{"class":99,"line":109},[1636,1640,1644,1649,1653,1658,1662,1666,1670],{"type":40,"tag":97,"props":1637,"children":1638},{"style":113},[1639],{"type":46,"value":1157},{"type":40,"tag":97,"props":1641,"children":1642},{"style":113},[1643],{"type":46,"value":1162},{"type":40,"tag":97,"props":1645,"children":1646},{"style":156},[1647],{"type":46,"value":1648}," decrementInventory",{"type":40,"tag":97,"props":1650,"children":1651},{"style":125},[1652],{"type":46,"value":164},{"type":40,"tag":97,"props":1654,"children":1655},{"style":1174},[1656],{"type":46,"value":1657},"productId",{"type":40,"tag":97,"props":1659,"children":1660},{"style":125},[1661],{"type":46,"value":180},{"type":40,"tag":97,"props":1663,"children":1664},{"style":1184},[1665],{"type":46,"value":1187},{"type":40,"tag":97,"props":1667,"children":1668},{"style":125},[1669],{"type":46,"value":205},{"type":40,"tag":97,"props":1671,"children":1672},{"style":125},[1673],{"type":46,"value":1196},{"type":40,"tag":97,"props":1675,"children":1676},{"class":99,"line":23},[1677,1682,1687,1692,1696,1700,1704,1708,1712,1717,1721],{"type":40,"tag":97,"props":1678,"children":1679},{"style":113},[1680],{"type":46,"value":1681},"  const",{"type":40,"tag":97,"props":1683,"children":1684},{"style":119},[1685],{"type":46,"value":1686}," result",{"type":40,"tag":97,"props":1688,"children":1689},{"style":125},[1690],{"type":46,"value":1691}," =",{"type":40,"tag":97,"props":1693,"children":1694},{"style":131},[1695],{"type":46,"value":134},{"type":40,"tag":97,"props":1697,"children":1698},{"style":119},[1699],{"type":46,"value":139},{"type":40,"tag":97,"props":1701,"children":1702},{"style":125},[1703],{"type":46,"value":144},{"type":40,"tag":97,"props":1705,"children":1706},{"style":119},[1707],{"type":46,"value":363},{"type":40,"tag":97,"props":1709,"children":1710},{"style":125},[1711],{"type":46,"value":144},{"type":40,"tag":97,"props":1713,"children":1714},{"style":156},[1715],{"type":46,"value":1716},"updateMany",{"type":40,"tag":97,"props":1718,"children":1719},{"style":172},[1720],{"type":46,"value":164},{"type":40,"tag":97,"props":1722,"children":1723},{"style":125},[1724],{"type":46,"value":1312},{"type":40,"tag":97,"props":1726,"children":1727},{"class":99,"line":503},[1728,1733,1737,1741,1745,1749,1754,1758,1762,1766,1770,1775,1779,1783,1787],{"type":40,"tag":97,"props":1729,"children":1730},{"style":172},[1731],{"type":46,"value":1732},"    where",{"type":40,"tag":97,"props":1734,"children":1735},{"style":125},[1736],{"type":46,"value":180},{"type":40,"tag":97,"props":1738,"children":1739},{"style":125},[1740],{"type":46,"value":185},{"type":40,"tag":97,"props":1742,"children":1743},{"style":172},[1744],{"type":46,"value":396},{"type":40,"tag":97,"props":1746,"children":1747},{"style":125},[1748],{"type":46,"value":180},{"type":40,"tag":97,"props":1750,"children":1751},{"style":119},[1752],{"type":46,"value":1753}," productId",{"type":40,"tag":97,"props":1755,"children":1756},{"style":125},[1757],{"type":46,"value":1576},{"type":40,"tag":97,"props":1759,"children":1760},{"style":172},[1761],{"type":46,"value":584},{"type":40,"tag":97,"props":1763,"children":1764},{"style":125},[1765],{"type":46,"value":180},{"type":40,"tag":97,"props":1767,"children":1768},{"style":125},[1769],{"type":46,"value":185},{"type":40,"tag":97,"props":1771,"children":1772},{"style":172},[1773],{"type":46,"value":1774}," gt",{"type":40,"tag":97,"props":1776,"children":1777},{"style":125},[1778],{"type":46,"value":180},{"type":40,"tag":97,"props":1780,"children":1781},{"style":450},[1782],{"type":46,"value":453},{"type":40,"tag":97,"props":1784,"children":1785},{"style":125},[1786],{"type":46,"value":200},{"type":40,"tag":97,"props":1788,"children":1789},{"style":125},[1790],{"type":46,"value":1791}," },\n",{"type":40,"tag":97,"props":1793,"children":1794},{"class":99,"line":863},[1795,1800,1804,1808,1812,1816,1820,1825,1829,1833,1837],{"type":40,"tag":97,"props":1796,"children":1797},{"style":172},[1798],{"type":46,"value":1799},"    data",{"type":40,"tag":97,"props":1801,"children":1802},{"style":125},[1803],{"type":46,"value":180},{"type":40,"tag":97,"props":1805,"children":1806},{"style":125},[1807],{"type":46,"value":185},{"type":40,"tag":97,"props":1809,"children":1810},{"style":172},[1811],{"type":46,"value":584},{"type":40,"tag":97,"props":1813,"children":1814},{"style":125},[1815],{"type":46,"value":180},{"type":40,"tag":97,"props":1817,"children":1818},{"style":125},[1819],{"type":46,"value":185},{"type":40,"tag":97,"props":1821,"children":1822},{"style":172},[1823],{"type":46,"value":1824}," decrement",{"type":40,"tag":97,"props":1826,"children":1827},{"style":125},[1828],{"type":46,"value":180},{"type":40,"tag":97,"props":1830,"children":1831},{"style":450},[1832],{"type":46,"value":611},{"type":40,"tag":97,"props":1834,"children":1835},{"style":125},[1836],{"type":46,"value":200},{"type":40,"tag":97,"props":1838,"children":1839},{"style":125},[1840],{"type":46,"value":1791},{"type":40,"tag":97,"props":1842,"children":1843},{"class":99,"line":1315},[1844,1848,1852],{"type":40,"tag":97,"props":1845,"children":1846},{"style":125},[1847],{"type":46,"value":1289},{"type":40,"tag":97,"props":1849,"children":1850},{"style":172},[1851],{"type":46,"value":205},{"type":40,"tag":97,"props":1853,"children":1854},{"style":125},[1855],{"type":46,"value":210},{"type":40,"tag":97,"props":1857,"children":1858},{"class":99,"line":1350},[1859,1864,1868,1873,1877,1882,1887,1891,1895,1899,1903,1907,1911,1915,1919,1923,1927],{"type":40,"tag":97,"props":1860,"children":1861},{"style":131},[1862],{"type":46,"value":1863},"  if",{"type":40,"tag":97,"props":1865,"children":1866},{"style":172},[1867],{"type":46,"value":223},{"type":40,"tag":97,"props":1869,"children":1870},{"style":119},[1871],{"type":46,"value":1872},"result",{"type":40,"tag":97,"props":1874,"children":1875},{"style":125},[1876],{"type":46,"value":144},{"type":40,"tag":97,"props":1878,"children":1879},{"style":119},[1880],{"type":46,"value":1881},"count",{"type":40,"tag":97,"props":1883,"children":1884},{"style":125},[1885],{"type":46,"value":1886}," ===",{"type":40,"tag":97,"props":1888,"children":1889},{"style":450},[1890],{"type":46,"value":453},{"type":40,"tag":97,"props":1892,"children":1893},{"style":172},[1894],{"type":46,"value":458},{"type":40,"tag":97,"props":1896,"children":1897},{"style":131},[1898],{"type":46,"value":463},{"type":40,"tag":97,"props":1900,"children":1901},{"style":125},[1902],{"type":46,"value":468},{"type":40,"tag":97,"props":1904,"children":1905},{"style":156},[1906],{"type":46,"value":473},{"type":40,"tag":97,"props":1908,"children":1909},{"style":172},[1910],{"type":46,"value":164},{"type":40,"tag":97,"props":1912,"children":1913},{"style":125},[1914],{"type":46,"value":482},{"type":40,"tag":97,"props":1916,"children":1917},{"style":485},[1918],{"type":46,"value":488},{"type":40,"tag":97,"props":1920,"children":1921},{"style":125},[1922],{"type":46,"value":482},{"type":40,"tag":97,"props":1924,"children":1925},{"style":172},[1926],{"type":46,"value":205},{"type":40,"tag":97,"props":1928,"children":1929},{"style":125},[1930],{"type":46,"value":210},{"type":40,"tag":97,"props":1932,"children":1933},{"class":99,"line":1423},[1934],{"type":40,"tag":97,"props":1935,"children":1936},{"style":125},[1937],{"type":46,"value":1465},{"type":40,"tag":73,"props":1939,"children":1941},{"id":1940},"conditional-status-transition-for-state-machines",[1942],{"type":46,"value":1943},"Conditional status transition (for state machines)",{"type":40,"tag":85,"props":1945,"children":1947},{"className":87,"code":1946,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: claim the transition atomically (UPDATE ... SET status='shipping' WHERE id=? AND status='paid') before any side effect\nasync function shipOrder(orderId: string) {\n  const result = await db.order.updateMany({\n    where: { id: orderId, status: \"paid\" },\n    data: { status: \"shipping\" }, \u002F\u002F claim it first\n  });\n  if (result.count === 0) throw new Error(\"Order not in paid state\");\n\n  await externalShippingApi.createShipment(orderId); \u002F\u002F now safe -- we own this transition\n  await db.order.update({ where: { id: orderId }, data: { status: \"shipped\" } });\n}\n",[1948],{"type":40,"tag":93,"props":1949,"children":1950},{"__ignoreMap":90},[1951,1959,2000,2047,2103,2149,2164,2236,2243,2284,2395],{"type":40,"tag":97,"props":1952,"children":1953},{"class":99,"line":27},[1954],{"type":40,"tag":97,"props":1955,"children":1956},{"style":103},[1957],{"type":46,"value":1958},"\u002F\u002F SAFE: claim the transition atomically (UPDATE ... SET status='shipping' WHERE id=? AND status='paid') before any side effect\n",{"type":40,"tag":97,"props":1960,"children":1961},{"class":99,"line":109},[1962,1966,1970,1975,1979,1984,1988,1992,1996],{"type":40,"tag":97,"props":1963,"children":1964},{"style":113},[1965],{"type":46,"value":1157},{"type":40,"tag":97,"props":1967,"children":1968},{"style":113},[1969],{"type":46,"value":1162},{"type":40,"tag":97,"props":1971,"children":1972},{"style":156},[1973],{"type":46,"value":1974}," shipOrder",{"type":40,"tag":97,"props":1976,"children":1977},{"style":125},[1978],{"type":46,"value":164},{"type":40,"tag":97,"props":1980,"children":1981},{"style":1174},[1982],{"type":46,"value":1983},"orderId",{"type":40,"tag":97,"props":1985,"children":1986},{"style":125},[1987],{"type":46,"value":180},{"type":40,"tag":97,"props":1989,"children":1990},{"style":1184},[1991],{"type":46,"value":1187},{"type":40,"tag":97,"props":1993,"children":1994},{"style":125},[1995],{"type":46,"value":205},{"type":40,"tag":97,"props":1997,"children":1998},{"style":125},[1999],{"type":46,"value":1196},{"type":40,"tag":97,"props":2001,"children":2002},{"class":99,"line":23},[2003,2007,2011,2015,2019,2023,2027,2031,2035,2039,2043],{"type":40,"tag":97,"props":2004,"children":2005},{"style":113},[2006],{"type":46,"value":1681},{"type":40,"tag":97,"props":2008,"children":2009},{"style":119},[2010],{"type":46,"value":1686},{"type":40,"tag":97,"props":2012,"children":2013},{"style":125},[2014],{"type":46,"value":1691},{"type":40,"tag":97,"props":2016,"children":2017},{"style":131},[2018],{"type":46,"value":134},{"type":40,"tag":97,"props":2020,"children":2021},{"style":119},[2022],{"type":46,"value":139},{"type":40,"tag":97,"props":2024,"children":2025},{"style":125},[2026],{"type":46,"value":144},{"type":40,"tag":97,"props":2028,"children":2029},{"style":119},[2030],{"type":46,"value":686},{"type":40,"tag":97,"props":2032,"children":2033},{"style":125},[2034],{"type":46,"value":144},{"type":40,"tag":97,"props":2036,"children":2037},{"style":156},[2038],{"type":46,"value":1716},{"type":40,"tag":97,"props":2040,"children":2041},{"style":172},[2042],{"type":46,"value":164},{"type":40,"tag":97,"props":2044,"children":2045},{"style":125},[2046],{"type":46,"value":1312},{"type":40,"tag":97,"props":2048,"children":2049},{"class":99,"line":503},[2050,2054,2058,2062,2066,2070,2075,2079,2083,2087,2091,2095,2099],{"type":40,"tag":97,"props":2051,"children":2052},{"style":172},[2053],{"type":46,"value":1732},{"type":40,"tag":97,"props":2055,"children":2056},{"style":125},[2057],{"type":46,"value":180},{"type":40,"tag":97,"props":2059,"children":2060},{"style":125},[2061],{"type":46,"value":185},{"type":40,"tag":97,"props":2063,"children":2064},{"style":172},[2065],{"type":46,"value":396},{"type":40,"tag":97,"props":2067,"children":2068},{"style":125},[2069],{"type":46,"value":180},{"type":40,"tag":97,"props":2071,"children":2072},{"style":119},[2073],{"type":46,"value":2074}," orderId",{"type":40,"tag":97,"props":2076,"children":2077},{"style":125},[2078],{"type":46,"value":1576},{"type":40,"tag":97,"props":2080,"children":2081},{"style":172},[2082],{"type":46,"value":941},{"type":40,"tag":97,"props":2084,"children":2085},{"style":125},[2086],{"type":46,"value":180},{"type":40,"tag":97,"props":2088,"children":2089},{"style":125},[2090],{"type":46,"value":774},{"type":40,"tag":97,"props":2092,"children":2093},{"style":485},[2094],{"type":46,"value":779},{"type":40,"tag":97,"props":2096,"children":2097},{"style":125},[2098],{"type":46,"value":482},{"type":40,"tag":97,"props":2100,"children":2101},{"style":125},[2102],{"type":46,"value":1791},{"type":40,"tag":97,"props":2104,"children":2105},{"class":99,"line":863},[2106,2110,2114,2118,2122,2126,2130,2135,2139,2144],{"type":40,"tag":97,"props":2107,"children":2108},{"style":172},[2109],{"type":46,"value":1799},{"type":40,"tag":97,"props":2111,"children":2112},{"style":125},[2113],{"type":46,"value":180},{"type":40,"tag":97,"props":2115,"children":2116},{"style":125},[2117],{"type":46,"value":185},{"type":40,"tag":97,"props":2119,"children":2120},{"style":172},[2121],{"type":46,"value":941},{"type":40,"tag":97,"props":2123,"children":2124},{"style":125},[2125],{"type":46,"value":180},{"type":40,"tag":97,"props":2127,"children":2128},{"style":125},[2129],{"type":46,"value":774},{"type":40,"tag":97,"props":2131,"children":2132},{"style":485},[2133],{"type":46,"value":2134},"shipping",{"type":40,"tag":97,"props":2136,"children":2137},{"style":125},[2138],{"type":46,"value":482},{"type":40,"tag":97,"props":2140,"children":2141},{"style":125},[2142],{"type":46,"value":2143}," },",{"type":40,"tag":97,"props":2145,"children":2146},{"style":103},[2147],{"type":46,"value":2148}," \u002F\u002F claim it first\n",{"type":40,"tag":97,"props":2150,"children":2151},{"class":99,"line":1315},[2152,2156,2160],{"type":40,"tag":97,"props":2153,"children":2154},{"style":125},[2155],{"type":46,"value":1289},{"type":40,"tag":97,"props":2157,"children":2158},{"style":172},[2159],{"type":46,"value":205},{"type":40,"tag":97,"props":2161,"children":2162},{"style":125},[2163],{"type":46,"value":210},{"type":40,"tag":97,"props":2165,"children":2166},{"class":99,"line":1350},[2167,2171,2175,2179,2183,2187,2191,2195,2199,2203,2207,2211,2215,2219,2224,2228,2232],{"type":40,"tag":97,"props":2168,"children":2169},{"style":131},[2170],{"type":46,"value":1863},{"type":40,"tag":97,"props":2172,"children":2173},{"style":172},[2174],{"type":46,"value":223},{"type":40,"tag":97,"props":2176,"children":2177},{"style":119},[2178],{"type":46,"value":1872},{"type":40,"tag":97,"props":2180,"children":2181},{"style":125},[2182],{"type":46,"value":144},{"type":40,"tag":97,"props":2184,"children":2185},{"style":119},[2186],{"type":46,"value":1881},{"type":40,"tag":97,"props":2188,"children":2189},{"style":125},[2190],{"type":46,"value":1886},{"type":40,"tag":97,"props":2192,"children":2193},{"style":450},[2194],{"type":46,"value":453},{"type":40,"tag":97,"props":2196,"children":2197},{"style":172},[2198],{"type":46,"value":458},{"type":40,"tag":97,"props":2200,"children":2201},{"style":131},[2202],{"type":46,"value":463},{"type":40,"tag":97,"props":2204,"children":2205},{"style":125},[2206],{"type":46,"value":468},{"type":40,"tag":97,"props":2208,"children":2209},{"style":156},[2210],{"type":46,"value":473},{"type":40,"tag":97,"props":2212,"children":2213},{"style":172},[2214],{"type":46,"value":164},{"type":40,"tag":97,"props":2216,"children":2217},{"style":125},[2218],{"type":46,"value":482},{"type":40,"tag":97,"props":2220,"children":2221},{"style":485},[2222],{"type":46,"value":2223},"Order not in paid state",{"type":40,"tag":97,"props":2225,"children":2226},{"style":125},[2227],{"type":46,"value":482},{"type":40,"tag":97,"props":2229,"children":2230},{"style":172},[2231],{"type":46,"value":205},{"type":40,"tag":97,"props":2233,"children":2234},{"style":125},[2235],{"type":46,"value":210},{"type":40,"tag":97,"props":2237,"children":2238},{"class":99,"line":1423},[2239],{"type":40,"tag":97,"props":2240,"children":2241},{"emptyLinePlaceholder":1472},[2242],{"type":46,"value":1475},{"type":40,"tag":97,"props":2244,"children":2245},{"class":99,"line":1432},[2246,2251,2255,2259,2263,2267,2271,2275,2279],{"type":40,"tag":97,"props":2247,"children":2248},{"style":131},[2249],{"type":46,"value":2250},"  await",{"type":40,"tag":97,"props":2252,"children":2253},{"style":119},[2254],{"type":46,"value":836},{"type":40,"tag":97,"props":2256,"children":2257},{"style":125},[2258],{"type":46,"value":144},{"type":40,"tag":97,"props":2260,"children":2261},{"style":156},[2262],{"type":46,"value":845},{"type":40,"tag":97,"props":2264,"children":2265},{"style":172},[2266],{"type":46,"value":164},{"type":40,"tag":97,"props":2268,"children":2269},{"style":119},[2270],{"type":46,"value":1983},{"type":40,"tag":97,"props":2272,"children":2273},{"style":172},[2274],{"type":46,"value":205},{"type":40,"tag":97,"props":2276,"children":2277},{"style":125},[2278],{"type":46,"value":855},{"type":40,"tag":97,"props":2280,"children":2281},{"style":103},[2282],{"type":46,"value":2283}," \u002F\u002F now safe -- we own this transition\n",{"type":40,"tag":97,"props":2285,"children":2286},{"class":99,"line":1450},[2287,2291,2295,2299,2303,2307,2311,2315,2319,2323,2327,2331,2335,2339,2343,2347,2351,2355,2359,2363,2367,2371,2375,2379,2383,2387,2391],{"type":40,"tag":97,"props":2288,"children":2289},{"style":131},[2290],{"type":46,"value":2250},{"type":40,"tag":97,"props":2292,"children":2293},{"style":119},[2294],{"type":46,"value":139},{"type":40,"tag":97,"props":2296,"children":2297},{"style":125},[2298],{"type":46,"value":144},{"type":40,"tag":97,"props":2300,"children":2301},{"style":119},[2302],{"type":46,"value":686},{"type":40,"tag":97,"props":2304,"children":2305},{"style":125},[2306],{"type":46,"value":144},{"type":40,"tag":97,"props":2308,"children":2309},{"style":156},[2310],{"type":46,"value":530},{"type":40,"tag":97,"props":2312,"children":2313},{"style":172},[2314],{"type":46,"value":164},{"type":40,"tag":97,"props":2316,"children":2317},{"style":125},[2318],{"type":46,"value":169},{"type":40,"tag":97,"props":2320,"children":2321},{"style":172},[2322],{"type":46,"value":175},{"type":40,"tag":97,"props":2324,"children":2325},{"style":125},[2326],{"type":46,"value":180},{"type":40,"tag":97,"props":2328,"children":2329},{"style":125},[2330],{"type":46,"value":185},{"type":40,"tag":97,"props":2332,"children":2333},{"style":172},[2334],{"type":46,"value":396},{"type":40,"tag":97,"props":2336,"children":2337},{"style":125},[2338],{"type":46,"value":180},{"type":40,"tag":97,"props":2340,"children":2341},{"style":119},[2342],{"type":46,"value":2074},{"type":40,"tag":97,"props":2344,"children":2345},{"style":125},[2346],{"type":46,"value":2143},{"type":40,"tag":97,"props":2348,"children":2349},{"style":172},[2350],{"type":46,"value":276},{"type":40,"tag":97,"props":2352,"children":2353},{"style":125},[2354],{"type":46,"value":180},{"type":40,"tag":97,"props":2356,"children":2357},{"style":125},[2358],{"type":46,"value":185},{"type":40,"tag":97,"props":2360,"children":2361},{"style":172},[2362],{"type":46,"value":941},{"type":40,"tag":97,"props":2364,"children":2365},{"style":125},[2366],{"type":46,"value":180},{"type":40,"tag":97,"props":2368,"children":2369},{"style":125},[2370],{"type":46,"value":774},{"type":40,"tag":97,"props":2372,"children":2373},{"style":485},[2374],{"type":46,"value":954},{"type":40,"tag":97,"props":2376,"children":2377},{"style":125},[2378],{"type":46,"value":482},{"type":40,"tag":97,"props":2380,"children":2381},{"style":125},[2382],{"type":46,"value":200},{"type":40,"tag":97,"props":2384,"children":2385},{"style":125},[2386],{"type":46,"value":200},{"type":40,"tag":97,"props":2388,"children":2389},{"style":172},[2390],{"type":46,"value":205},{"type":40,"tag":97,"props":2392,"children":2393},{"style":125},[2394],{"type":46,"value":210},{"type":40,"tag":97,"props":2396,"children":2397},{"class":99,"line":1459},[2398],{"type":40,"tag":97,"props":2399,"children":2400},{"style":125},[2401],{"type":46,"value":1465},{"type":40,"tag":73,"props":2403,"children":2405},{"id":2404},"optimistic-locking-with-version-column",[2406],{"type":46,"value":2407},"Optimistic locking with version column",{"type":40,"tag":85,"props":2409,"children":2411},{"className":87,"code":2410,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: detects concurrent modification via version mismatch\nasync function updateDocument(docId: string, changes: Partial\u003CDoc>) {\n  const doc = await db.document.findUnique({ where: { id: docId } });\n  const result = await db.document.updateMany({\n    where: { id: docId, version: doc.version },\n    data: { ...changes, version: doc.version + 1 },\n  });\n  if (result.count === 0) throw new ConflictError(\"Document was modified by another process\");\n}\n",[2412],{"type":40,"tag":93,"props":2413,"children":2414},{"__ignoreMap":90},[2415,2423,2493,2583,2630,2687,2749,2764,2837],{"type":40,"tag":97,"props":2416,"children":2417},{"class":99,"line":27},[2418],{"type":40,"tag":97,"props":2419,"children":2420},{"style":103},[2421],{"type":46,"value":2422},"\u002F\u002F SAFE: detects concurrent modification via version mismatch\n",{"type":40,"tag":97,"props":2424,"children":2425},{"class":99,"line":109},[2426,2430,2434,2439,2443,2448,2452,2456,2460,2465,2469,2474,2479,2484,2489],{"type":40,"tag":97,"props":2427,"children":2428},{"style":113},[2429],{"type":46,"value":1157},{"type":40,"tag":97,"props":2431,"children":2432},{"style":113},[2433],{"type":46,"value":1162},{"type":40,"tag":97,"props":2435,"children":2436},{"style":156},[2437],{"type":46,"value":2438}," updateDocument",{"type":40,"tag":97,"props":2440,"children":2441},{"style":125},[2442],{"type":46,"value":164},{"type":40,"tag":97,"props":2444,"children":2445},{"style":1174},[2446],{"type":46,"value":2447},"docId",{"type":40,"tag":97,"props":2449,"children":2450},{"style":125},[2451],{"type":46,"value":180},{"type":40,"tag":97,"props":2453,"children":2454},{"style":1184},[2455],{"type":46,"value":1187},{"type":40,"tag":97,"props":2457,"children":2458},{"style":125},[2459],{"type":46,"value":1576},{"type":40,"tag":97,"props":2461,"children":2462},{"style":1174},[2463],{"type":46,"value":2464}," changes",{"type":40,"tag":97,"props":2466,"children":2467},{"style":125},[2468],{"type":46,"value":180},{"type":40,"tag":97,"props":2470,"children":2471},{"style":1184},[2472],{"type":46,"value":2473}," Partial",{"type":40,"tag":97,"props":2475,"children":2476},{"style":125},[2477],{"type":46,"value":2478},"\u003C",{"type":40,"tag":97,"props":2480,"children":2481},{"style":1184},[2482],{"type":46,"value":2483},"Doc",{"type":40,"tag":97,"props":2485,"children":2486},{"style":125},[2487],{"type":46,"value":2488},">)",{"type":40,"tag":97,"props":2490,"children":2491},{"style":125},[2492],{"type":46,"value":1196},{"type":40,"tag":97,"props":2494,"children":2495},{"class":99,"line":23},[2496,2500,2505,2509,2513,2517,2521,2526,2530,2534,2538,2542,2546,2550,2554,2558,2562,2567,2571,2575,2579],{"type":40,"tag":97,"props":2497,"children":2498},{"style":113},[2499],{"type":46,"value":1681},{"type":40,"tag":97,"props":2501,"children":2502},{"style":119},[2503],{"type":46,"value":2504}," doc",{"type":40,"tag":97,"props":2506,"children":2507},{"style":125},[2508],{"type":46,"value":1691},{"type":40,"tag":97,"props":2510,"children":2511},{"style":131},[2512],{"type":46,"value":134},{"type":40,"tag":97,"props":2514,"children":2515},{"style":119},[2516],{"type":46,"value":139},{"type":40,"tag":97,"props":2518,"children":2519},{"style":125},[2520],{"type":46,"value":144},{"type":40,"tag":97,"props":2522,"children":2523},{"style":119},[2524],{"type":46,"value":2525},"document",{"type":40,"tag":97,"props":2527,"children":2528},{"style":125},[2529],{"type":46,"value":144},{"type":40,"tag":97,"props":2531,"children":2532},{"style":156},[2533],{"type":46,"value":159},{"type":40,"tag":97,"props":2535,"children":2536},{"style":172},[2537],{"type":46,"value":164},{"type":40,"tag":97,"props":2539,"children":2540},{"style":125},[2541],{"type":46,"value":169},{"type":40,"tag":97,"props":2543,"children":2544},{"style":172},[2545],{"type":46,"value":175},{"type":40,"tag":97,"props":2547,"children":2548},{"style":125},[2549],{"type":46,"value":180},{"type":40,"tag":97,"props":2551,"children":2552},{"style":125},[2553],{"type":46,"value":185},{"type":40,"tag":97,"props":2555,"children":2556},{"style":172},[2557],{"type":46,"value":396},{"type":40,"tag":97,"props":2559,"children":2560},{"style":125},[2561],{"type":46,"value":180},{"type":40,"tag":97,"props":2563,"children":2564},{"style":119},[2565],{"type":46,"value":2566}," docId",{"type":40,"tag":97,"props":2568,"children":2569},{"style":125},[2570],{"type":46,"value":200},{"type":40,"tag":97,"props":2572,"children":2573},{"style":125},[2574],{"type":46,"value":200},{"type":40,"tag":97,"props":2576,"children":2577},{"style":172},[2578],{"type":46,"value":205},{"type":40,"tag":97,"props":2580,"children":2581},{"style":125},[2582],{"type":46,"value":210},{"type":40,"tag":97,"props":2584,"children":2585},{"class":99,"line":503},[2586,2590,2594,2598,2602,2606,2610,2614,2618,2622,2626],{"type":40,"tag":97,"props":2587,"children":2588},{"style":113},[2589],{"type":46,"value":1681},{"type":40,"tag":97,"props":2591,"children":2592},{"style":119},[2593],{"type":46,"value":1686},{"type":40,"tag":97,"props":2595,"children":2596},{"style":125},[2597],{"type":46,"value":1691},{"type":40,"tag":97,"props":2599,"children":2600},{"style":131},[2601],{"type":46,"value":134},{"type":40,"tag":97,"props":2603,"children":2604},{"style":119},[2605],{"type":46,"value":139},{"type":40,"tag":97,"props":2607,"children":2608},{"style":125},[2609],{"type":46,"value":144},{"type":40,"tag":97,"props":2611,"children":2612},{"style":119},[2613],{"type":46,"value":2525},{"type":40,"tag":97,"props":2615,"children":2616},{"style":125},[2617],{"type":46,"value":144},{"type":40,"tag":97,"props":2619,"children":2620},{"style":156},[2621],{"type":46,"value":1716},{"type":40,"tag":97,"props":2623,"children":2624},{"style":172},[2625],{"type":46,"value":164},{"type":40,"tag":97,"props":2627,"children":2628},{"style":125},[2629],{"type":46,"value":1312},{"type":40,"tag":97,"props":2631,"children":2632},{"class":99,"line":863},[2633,2637,2641,2645,2649,2653,2657,2661,2666,2670,2674,2678,2683],{"type":40,"tag":97,"props":2634,"children":2635},{"style":172},[2636],{"type":46,"value":1732},{"type":40,"tag":97,"props":2638,"children":2639},{"style":125},[2640],{"type":46,"value":180},{"type":40,"tag":97,"props":2642,"children":2643},{"style":125},[2644],{"type":46,"value":185},{"type":40,"tag":97,"props":2646,"children":2647},{"style":172},[2648],{"type":46,"value":396},{"type":40,"tag":97,"props":2650,"children":2651},{"style":125},[2652],{"type":46,"value":180},{"type":40,"tag":97,"props":2654,"children":2655},{"style":119},[2656],{"type":46,"value":2566},{"type":40,"tag":97,"props":2658,"children":2659},{"style":125},[2660],{"type":46,"value":1576},{"type":40,"tag":97,"props":2662,"children":2663},{"style":172},[2664],{"type":46,"value":2665}," version",{"type":40,"tag":97,"props":2667,"children":2668},{"style":125},[2669],{"type":46,"value":180},{"type":40,"tag":97,"props":2671,"children":2672},{"style":119},[2673],{"type":46,"value":2504},{"type":40,"tag":97,"props":2675,"children":2676},{"style":125},[2677],{"type":46,"value":144},{"type":40,"tag":97,"props":2679,"children":2680},{"style":119},[2681],{"type":46,"value":2682},"version",{"type":40,"tag":97,"props":2684,"children":2685},{"style":125},[2686],{"type":46,"value":1791},{"type":40,"tag":97,"props":2688,"children":2689},{"class":99,"line":1315},[2690,2694,2698,2702,2707,2712,2716,2720,2724,2728,2732,2736,2741,2745],{"type":40,"tag":97,"props":2691,"children":2692},{"style":172},[2693],{"type":46,"value":1799},{"type":40,"tag":97,"props":2695,"children":2696},{"style":125},[2697],{"type":46,"value":180},{"type":40,"tag":97,"props":2699,"children":2700},{"style":125},[2701],{"type":46,"value":185},{"type":40,"tag":97,"props":2703,"children":2704},{"style":125},[2705],{"type":46,"value":2706}," ...",{"type":40,"tag":97,"props":2708,"children":2709},{"style":119},[2710],{"type":46,"value":2711},"changes",{"type":40,"tag":97,"props":2713,"children":2714},{"style":125},[2715],{"type":46,"value":1576},{"type":40,"tag":97,"props":2717,"children":2718},{"style":172},[2719],{"type":46,"value":2665},{"type":40,"tag":97,"props":2721,"children":2722},{"style":125},[2723],{"type":46,"value":180},{"type":40,"tag":97,"props":2725,"children":2726},{"style":119},[2727],{"type":46,"value":2504},{"type":40,"tag":97,"props":2729,"children":2730},{"style":125},[2731],{"type":46,"value":144},{"type":40,"tag":97,"props":2733,"children":2734},{"style":119},[2735],{"type":46,"value":2682},{"type":40,"tag":97,"props":2737,"children":2738},{"style":125},[2739],{"type":46,"value":2740}," +",{"type":40,"tag":97,"props":2742,"children":2743},{"style":450},[2744],{"type":46,"value":611},{"type":40,"tag":97,"props":2746,"children":2747},{"style":125},[2748],{"type":46,"value":1791},{"type":40,"tag":97,"props":2750,"children":2751},{"class":99,"line":1350},[2752,2756,2760],{"type":40,"tag":97,"props":2753,"children":2754},{"style":125},[2755],{"type":46,"value":1289},{"type":40,"tag":97,"props":2757,"children":2758},{"style":172},[2759],{"type":46,"value":205},{"type":40,"tag":97,"props":2761,"children":2762},{"style":125},[2763],{"type":46,"value":210},{"type":40,"tag":97,"props":2765,"children":2766},{"class":99,"line":1423},[2767,2771,2775,2779,2783,2787,2791,2795,2799,2803,2807,2812,2816,2820,2825,2829,2833],{"type":40,"tag":97,"props":2768,"children":2769},{"style":131},[2770],{"type":46,"value":1863},{"type":40,"tag":97,"props":2772,"children":2773},{"style":172},[2774],{"type":46,"value":223},{"type":40,"tag":97,"props":2776,"children":2777},{"style":119},[2778],{"type":46,"value":1872},{"type":40,"tag":97,"props":2780,"children":2781},{"style":125},[2782],{"type":46,"value":144},{"type":40,"tag":97,"props":2784,"children":2785},{"style":119},[2786],{"type":46,"value":1881},{"type":40,"tag":97,"props":2788,"children":2789},{"style":125},[2790],{"type":46,"value":1886},{"type":40,"tag":97,"props":2792,"children":2793},{"style":450},[2794],{"type":46,"value":453},{"type":40,"tag":97,"props":2796,"children":2797},{"style":172},[2798],{"type":46,"value":458},{"type":40,"tag":97,"props":2800,"children":2801},{"style":131},[2802],{"type":46,"value":463},{"type":40,"tag":97,"props":2804,"children":2805},{"style":125},[2806],{"type":46,"value":468},{"type":40,"tag":97,"props":2808,"children":2809},{"style":156},[2810],{"type":46,"value":2811}," ConflictError",{"type":40,"tag":97,"props":2813,"children":2814},{"style":172},[2815],{"type":46,"value":164},{"type":40,"tag":97,"props":2817,"children":2818},{"style":125},[2819],{"type":46,"value":482},{"type":40,"tag":97,"props":2821,"children":2822},{"style":485},[2823],{"type":46,"value":2824},"Document was modified by another process",{"type":40,"tag":97,"props":2826,"children":2827},{"style":125},[2828],{"type":46,"value":482},{"type":40,"tag":97,"props":2830,"children":2831},{"style":172},[2832],{"type":46,"value":205},{"type":40,"tag":97,"props":2834,"children":2835},{"style":125},[2836],{"type":46,"value":210},{"type":40,"tag":97,"props":2838,"children":2839},{"class":99,"line":1432},[2840],{"type":40,"tag":97,"props":2841,"children":2842},{"style":125},[2843],{"type":46,"value":1465},{"type":40,"tag":73,"props":2845,"children":2847},{"id":2846},"pessimistic-locking-when-you-must-hold-state-across-external-calls",[2848],{"type":46,"value":2849},"Pessimistic locking (when you must hold state across external calls)",{"type":40,"tag":85,"props":2851,"children":2853},{"className":87,"code":2852,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: FOR UPDATE locks the row, serializing concurrent access\nasync function processPayment(orderId: string) {\n  await db.$transaction(async (tx) => {\n    const order = await tx.$queryRaw`SELECT * FROM orders WHERE id = ${orderId} FOR UPDATE`;\n    if (order.status !== \"pending\") throw new Error(\"Already processed\");\n\n    const charge = await stripe.charges.create({ amount: order.total });\n    await tx.order.update({\n      where: { id: orderId },\n      data: { status: \"paid\", stripeChargeId: charge.id },\n    });\n  });\n}\n",[2854],{"type":40,"tag":93,"props":2855,"children":2856},{"__ignoreMap":90},[2857,2865,2905,2955,3026,3109,3116,3200,3236,3268,3334,3350,3365],{"type":40,"tag":97,"props":2858,"children":2859},{"class":99,"line":27},[2860],{"type":40,"tag":97,"props":2861,"children":2862},{"style":103},[2863],{"type":46,"value":2864},"\u002F\u002F SAFE: FOR UPDATE locks the row, serializing concurrent access\n",{"type":40,"tag":97,"props":2866,"children":2867},{"class":99,"line":109},[2868,2872,2876,2881,2885,2889,2893,2897,2901],{"type":40,"tag":97,"props":2869,"children":2870},{"style":113},[2871],{"type":46,"value":1157},{"type":40,"tag":97,"props":2873,"children":2874},{"style":113},[2875],{"type":46,"value":1162},{"type":40,"tag":97,"props":2877,"children":2878},{"style":156},[2879],{"type":46,"value":2880}," processPayment",{"type":40,"tag":97,"props":2882,"children":2883},{"style":125},[2884],{"type":46,"value":164},{"type":40,"tag":97,"props":2886,"children":2887},{"style":1174},[2888],{"type":46,"value":1983},{"type":40,"tag":97,"props":2890,"children":2891},{"style":125},[2892],{"type":46,"value":180},{"type":40,"tag":97,"props":2894,"children":2895},{"style":1184},[2896],{"type":46,"value":1187},{"type":40,"tag":97,"props":2898,"children":2899},{"style":125},[2900],{"type":46,"value":205},{"type":40,"tag":97,"props":2902,"children":2903},{"style":125},[2904],{"type":46,"value":1196},{"type":40,"tag":97,"props":2906,"children":2907},{"class":99,"line":23},[2908,2912,2916,2920,2925,2929,2933,2937,2942,2946,2951],{"type":40,"tag":97,"props":2909,"children":2910},{"style":131},[2911],{"type":46,"value":2250},{"type":40,"tag":97,"props":2913,"children":2914},{"style":119},[2915],{"type":46,"value":139},{"type":40,"tag":97,"props":2917,"children":2918},{"style":125},[2919],{"type":46,"value":144},{"type":40,"tag":97,"props":2921,"children":2922},{"style":156},[2923],{"type":46,"value":2924},"$transaction",{"type":40,"tag":97,"props":2926,"children":2927},{"style":172},[2928],{"type":46,"value":164},{"type":40,"tag":97,"props":2930,"children":2931},{"style":113},[2932],{"type":46,"value":1157},{"type":40,"tag":97,"props":2934,"children":2935},{"style":125},[2936],{"type":46,"value":223},{"type":40,"tag":97,"props":2938,"children":2939},{"style":1174},[2940],{"type":46,"value":2941},"tx",{"type":40,"tag":97,"props":2943,"children":2944},{"style":125},[2945],{"type":46,"value":205},{"type":40,"tag":97,"props":2947,"children":2948},{"style":113},[2949],{"type":46,"value":2950}," =>",{"type":40,"tag":97,"props":2952,"children":2953},{"style":125},[2954],{"type":46,"value":1196},{"type":40,"tag":97,"props":2956,"children":2957},{"class":99,"line":503},[2958,2963,2968,2972,2976,2981,2985,2990,2995,3000,3005,3009,3013,3018,3022],{"type":40,"tag":97,"props":2959,"children":2960},{"style":113},[2961],{"type":46,"value":2962},"    const",{"type":40,"tag":97,"props":2964,"children":2965},{"style":119},[2966],{"type":46,"value":2967}," order",{"type":40,"tag":97,"props":2969,"children":2970},{"style":125},[2971],{"type":46,"value":1691},{"type":40,"tag":97,"props":2973,"children":2974},{"style":131},[2975],{"type":46,"value":134},{"type":40,"tag":97,"props":2977,"children":2978},{"style":119},[2979],{"type":46,"value":2980}," tx",{"type":40,"tag":97,"props":2982,"children":2983},{"style":125},[2984],{"type":46,"value":144},{"type":40,"tag":97,"props":2986,"children":2987},{"style":156},[2988],{"type":46,"value":2989},"$queryRaw",{"type":40,"tag":97,"props":2991,"children":2992},{"style":125},[2993],{"type":46,"value":2994},"`",{"type":40,"tag":97,"props":2996,"children":2997},{"style":485},[2998],{"type":46,"value":2999},"SELECT * FROM orders WHERE id = ",{"type":40,"tag":97,"props":3001,"children":3002},{"style":125},[3003],{"type":46,"value":3004},"${",{"type":40,"tag":97,"props":3006,"children":3007},{"style":119},[3008],{"type":46,"value":1983},{"type":40,"tag":97,"props":3010,"children":3011},{"style":125},[3012],{"type":46,"value":195},{"type":40,"tag":97,"props":3014,"children":3015},{"style":485},[3016],{"type":46,"value":3017}," FOR UPDATE",{"type":40,"tag":97,"props":3019,"children":3020},{"style":125},[3021],{"type":46,"value":2994},{"type":40,"tag":97,"props":3023,"children":3024},{"style":125},[3025],{"type":46,"value":210},{"type":40,"tag":97,"props":3027,"children":3028},{"class":99,"line":863},[3029,3033,3037,3041,3045,3050,3055,3059,3064,3068,3072,3076,3080,3084,3088,3092,3097,3101,3105],{"type":40,"tag":97,"props":3030,"children":3031},{"style":131},[3032],{"type":46,"value":1321},{"type":40,"tag":97,"props":3034,"children":3035},{"style":172},[3036],{"type":46,"value":223},{"type":40,"tag":97,"props":3038,"children":3039},{"style":119},[3040],{"type":46,"value":686},{"type":40,"tag":97,"props":3042,"children":3043},{"style":125},[3044],{"type":46,"value":144},{"type":40,"tag":97,"props":3046,"children":3047},{"style":119},[3048],{"type":46,"value":3049},"status",{"type":40,"tag":97,"props":3051,"children":3052},{"style":125},[3053],{"type":46,"value":3054}," !==",{"type":40,"tag":97,"props":3056,"children":3057},{"style":125},[3058],{"type":46,"value":774},{"type":40,"tag":97,"props":3060,"children":3061},{"style":485},[3062],{"type":46,"value":3063},"pending",{"type":40,"tag":97,"props":3065,"children":3066},{"style":125},[3067],{"type":46,"value":482},{"type":40,"tag":97,"props":3069,"children":3070},{"style":172},[3071],{"type":46,"value":458},{"type":40,"tag":97,"props":3073,"children":3074},{"style":131},[3075],{"type":46,"value":463},{"type":40,"tag":97,"props":3077,"children":3078},{"style":125},[3079],{"type":46,"value":468},{"type":40,"tag":97,"props":3081,"children":3082},{"style":156},[3083],{"type":46,"value":473},{"type":40,"tag":97,"props":3085,"children":3086},{"style":172},[3087],{"type":46,"value":164},{"type":40,"tag":97,"props":3089,"children":3090},{"style":125},[3091],{"type":46,"value":482},{"type":40,"tag":97,"props":3093,"children":3094},{"style":485},[3095],{"type":46,"value":3096},"Already processed",{"type":40,"tag":97,"props":3098,"children":3099},{"style":125},[3100],{"type":46,"value":482},{"type":40,"tag":97,"props":3102,"children":3103},{"style":172},[3104],{"type":46,"value":205},{"type":40,"tag":97,"props":3106,"children":3107},{"style":125},[3108],{"type":46,"value":210},{"type":40,"tag":97,"props":3110,"children":3111},{"class":99,"line":1315},[3112],{"type":40,"tag":97,"props":3113,"children":3114},{"emptyLinePlaceholder":1472},[3115],{"type":46,"value":1475},{"type":40,"tag":97,"props":3117,"children":3118},{"class":99,"line":1350},[3119,3123,3128,3132,3136,3141,3145,3150,3154,3158,3162,3166,3171,3175,3179,3183,3188,3192,3196],{"type":40,"tag":97,"props":3120,"children":3121},{"style":113},[3122],{"type":46,"value":2962},{"type":40,"tag":97,"props":3124,"children":3125},{"style":119},[3126],{"type":46,"value":3127}," charge",{"type":40,"tag":97,"props":3129,"children":3130},{"style":125},[3131],{"type":46,"value":1691},{"type":40,"tag":97,"props":3133,"children":3134},{"style":131},[3135],{"type":46,"value":134},{"type":40,"tag":97,"props":3137,"children":3138},{"style":119},[3139],{"type":46,"value":3140}," stripe",{"type":40,"tag":97,"props":3142,"children":3143},{"style":125},[3144],{"type":46,"value":144},{"type":40,"tag":97,"props":3146,"children":3147},{"style":119},[3148],{"type":46,"value":3149},"charges",{"type":40,"tag":97,"props":3151,"children":3152},{"style":125},[3153],{"type":46,"value":144},{"type":40,"tag":97,"props":3155,"children":3156},{"style":156},[3157],{"type":46,"value":263},{"type":40,"tag":97,"props":3159,"children":3160},{"style":172},[3161],{"type":46,"value":164},{"type":40,"tag":97,"props":3163,"children":3164},{"style":125},[3165],{"type":46,"value":169},{"type":40,"tag":97,"props":3167,"children":3168},{"style":172},[3169],{"type":46,"value":3170}," amount",{"type":40,"tag":97,"props":3172,"children":3173},{"style":125},[3174],{"type":46,"value":180},{"type":40,"tag":97,"props":3176,"children":3177},{"style":119},[3178],{"type":46,"value":2967},{"type":40,"tag":97,"props":3180,"children":3181},{"style":125},[3182],{"type":46,"value":144},{"type":40,"tag":97,"props":3184,"children":3185},{"style":119},[3186],{"type":46,"value":3187},"total",{"type":40,"tag":97,"props":3189,"children":3190},{"style":125},[3191],{"type":46,"value":200},{"type":40,"tag":97,"props":3193,"children":3194},{"style":172},[3195],{"type":46,"value":205},{"type":40,"tag":97,"props":3197,"children":3198},{"style":125},[3199],{"type":46,"value":210},{"type":40,"tag":97,"props":3201,"children":3202},{"class":99,"line":1423},[3203,3208,3212,3216,3220,3224,3228,3232],{"type":40,"tag":97,"props":3204,"children":3205},{"style":131},[3206],{"type":46,"value":3207},"    await",{"type":40,"tag":97,"props":3209,"children":3210},{"style":119},[3211],{"type":46,"value":2980},{"type":40,"tag":97,"props":3213,"children":3214},{"style":125},[3215],{"type":46,"value":144},{"type":40,"tag":97,"props":3217,"children":3218},{"style":119},[3219],{"type":46,"value":686},{"type":40,"tag":97,"props":3221,"children":3222},{"style":125},[3223],{"type":46,"value":144},{"type":40,"tag":97,"props":3225,"children":3226},{"style":156},[3227],{"type":46,"value":530},{"type":40,"tag":97,"props":3229,"children":3230},{"style":172},[3231],{"type":46,"value":164},{"type":40,"tag":97,"props":3233,"children":3234},{"style":125},[3235],{"type":46,"value":1312},{"type":40,"tag":97,"props":3237,"children":3238},{"class":99,"line":1432},[3239,3244,3248,3252,3256,3260,3264],{"type":40,"tag":97,"props":3240,"children":3241},{"style":172},[3242],{"type":46,"value":3243},"      where",{"type":40,"tag":97,"props":3245,"children":3246},{"style":125},[3247],{"type":46,"value":180},{"type":40,"tag":97,"props":3249,"children":3250},{"style":125},[3251],{"type":46,"value":185},{"type":40,"tag":97,"props":3253,"children":3254},{"style":172},[3255],{"type":46,"value":396},{"type":40,"tag":97,"props":3257,"children":3258},{"style":125},[3259],{"type":46,"value":180},{"type":40,"tag":97,"props":3261,"children":3262},{"style":119},[3263],{"type":46,"value":2074},{"type":40,"tag":97,"props":3265,"children":3266},{"style":125},[3267],{"type":46,"value":1791},{"type":40,"tag":97,"props":3269,"children":3270},{"class":99,"line":1450},[3271,3276,3280,3284,3288,3292,3296,3300,3304,3308,3313,3317,3321,3325,3330],{"type":40,"tag":97,"props":3272,"children":3273},{"style":172},[3274],{"type":46,"value":3275},"      data",{"type":40,"tag":97,"props":3277,"children":3278},{"style":125},[3279],{"type":46,"value":180},{"type":40,"tag":97,"props":3281,"children":3282},{"style":125},[3283],{"type":46,"value":185},{"type":40,"tag":97,"props":3285,"children":3286},{"style":172},[3287],{"type":46,"value":941},{"type":40,"tag":97,"props":3289,"children":3290},{"style":125},[3291],{"type":46,"value":180},{"type":40,"tag":97,"props":3293,"children":3294},{"style":125},[3295],{"type":46,"value":774},{"type":40,"tag":97,"props":3297,"children":3298},{"style":485},[3299],{"type":46,"value":779},{"type":40,"tag":97,"props":3301,"children":3302},{"style":125},[3303],{"type":46,"value":482},{"type":40,"tag":97,"props":3305,"children":3306},{"style":125},[3307],{"type":46,"value":1576},{"type":40,"tag":97,"props":3309,"children":3310},{"style":172},[3311],{"type":46,"value":3312}," stripeChargeId",{"type":40,"tag":97,"props":3314,"children":3315},{"style":125},[3316],{"type":46,"value":180},{"type":40,"tag":97,"props":3318,"children":3319},{"style":119},[3320],{"type":46,"value":3127},{"type":40,"tag":97,"props":3322,"children":3323},{"style":125},[3324],{"type":46,"value":144},{"type":40,"tag":97,"props":3326,"children":3327},{"style":119},[3328],{"type":46,"value":3329},"id",{"type":40,"tag":97,"props":3331,"children":3332},{"style":125},[3333],{"type":46,"value":1791},{"type":40,"tag":97,"props":3335,"children":3336},{"class":99,"line":1459},[3337,3342,3346],{"type":40,"tag":97,"props":3338,"children":3339},{"style":125},[3340],{"type":46,"value":3341},"    }",{"type":40,"tag":97,"props":3343,"children":3344},{"style":172},[3345],{"type":46,"value":205},{"type":40,"tag":97,"props":3347,"children":3348},{"style":125},[3349],{"type":46,"value":210},{"type":40,"tag":97,"props":3351,"children":3352},{"class":99,"line":1468},[3353,3357,3361],{"type":40,"tag":97,"props":3354,"children":3355},{"style":125},[3356],{"type":46,"value":1289},{"type":40,"tag":97,"props":3358,"children":3359},{"style":172},[3360],{"type":46,"value":205},{"type":40,"tag":97,"props":3362,"children":3363},{"style":125},[3364],{"type":46,"value":210},{"type":40,"tag":97,"props":3366,"children":3367},{"class":99,"line":1478},[3368],{"type":40,"tag":97,"props":3369,"children":3370},{"style":125},[3371],{"type":46,"value":1465},{"type":40,"tag":49,"props":3373,"children":3374},{},[3375,3377,3383],{"type":46,"value":3376},"Use ",{"type":40,"tag":93,"props":3378,"children":3380},{"className":3379},[],[3381],{"type":46,"value":3382},"SELECT FOR UPDATE",{"type":46,"value":3384}," when you must read state, do external work (API calls), then write. Tradeoff: same-row operations serialize, reducing throughput.",{"type":40,"tag":61,"props":3386,"children":3388},{"id":3387},"redis-atomic-operations",[3389],{"type":46,"value":3390},"Redis Atomic Operations",{"type":40,"tag":49,"props":3392,"children":3393},{},[3394],{"type":46,"value":3395},"Redis commands are single-threaded and atomic. Use them for fast, atomic operations on shared counters, flags, or sets that don't need database durability.",{"type":40,"tag":73,"props":3397,"children":3399},{"id":3398},"atomic-counter",[3400],{"type":46,"value":3401},"Atomic counter",{"type":40,"tag":85,"props":3403,"children":3405},{"className":87,"code":3404,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: DECR is atomic; incr to undo if we went negative\nasync function decrementInventory(productId: string) {\n  const remaining = await redis.decr(`inventory:${productId}`);\n  if (remaining \u003C 0) {\n    await redis.incr(`inventory:${productId}`);\n    throw new Error(\"Out of stock\");\n  }\n}\n",[3406],{"type":40,"tag":93,"props":3407,"children":3408},{"__ignoreMap":90},[3409,3417,3456,3524,3557,3609,3648,3655],{"type":40,"tag":97,"props":3410,"children":3411},{"class":99,"line":27},[3412],{"type":40,"tag":97,"props":3413,"children":3414},{"style":103},[3415],{"type":46,"value":3416},"\u002F\u002F SAFE: DECR is atomic; incr to undo if we went negative\n",{"type":40,"tag":97,"props":3418,"children":3419},{"class":99,"line":109},[3420,3424,3428,3432,3436,3440,3444,3448,3452],{"type":40,"tag":97,"props":3421,"children":3422},{"style":113},[3423],{"type":46,"value":1157},{"type":40,"tag":97,"props":3425,"children":3426},{"style":113},[3427],{"type":46,"value":1162},{"type":40,"tag":97,"props":3429,"children":3430},{"style":156},[3431],{"type":46,"value":1648},{"type":40,"tag":97,"props":3433,"children":3434},{"style":125},[3435],{"type":46,"value":164},{"type":40,"tag":97,"props":3437,"children":3438},{"style":1174},[3439],{"type":46,"value":1657},{"type":40,"tag":97,"props":3441,"children":3442},{"style":125},[3443],{"type":46,"value":180},{"type":40,"tag":97,"props":3445,"children":3446},{"style":1184},[3447],{"type":46,"value":1187},{"type":40,"tag":97,"props":3449,"children":3450},{"style":125},[3451],{"type":46,"value":205},{"type":40,"tag":97,"props":3453,"children":3454},{"style":125},[3455],{"type":46,"value":1196},{"type":40,"tag":97,"props":3457,"children":3458},{"class":99,"line":23},[3459,3463,3468,3472,3476,3481,3485,3490,3494,3498,3503,3507,3511,3516,3520],{"type":40,"tag":97,"props":3460,"children":3461},{"style":113},[3462],{"type":46,"value":1681},{"type":40,"tag":97,"props":3464,"children":3465},{"style":119},[3466],{"type":46,"value":3467}," remaining",{"type":40,"tag":97,"props":3469,"children":3470},{"style":125},[3471],{"type":46,"value":1691},{"type":40,"tag":97,"props":3473,"children":3474},{"style":131},[3475],{"type":46,"value":134},{"type":40,"tag":97,"props":3477,"children":3478},{"style":119},[3479],{"type":46,"value":3480}," redis",{"type":40,"tag":97,"props":3482,"children":3483},{"style":125},[3484],{"type":46,"value":144},{"type":40,"tag":97,"props":3486,"children":3487},{"style":156},[3488],{"type":46,"value":3489},"decr",{"type":40,"tag":97,"props":3491,"children":3492},{"style":172},[3493],{"type":46,"value":164},{"type":40,"tag":97,"props":3495,"children":3496},{"style":125},[3497],{"type":46,"value":2994},{"type":40,"tag":97,"props":3499,"children":3500},{"style":485},[3501],{"type":46,"value":3502},"inventory:",{"type":40,"tag":97,"props":3504,"children":3505},{"style":125},[3506],{"type":46,"value":3004},{"type":40,"tag":97,"props":3508,"children":3509},{"style":119},[3510],{"type":46,"value":1657},{"type":40,"tag":97,"props":3512,"children":3513},{"style":125},[3514],{"type":46,"value":3515},"}`",{"type":40,"tag":97,"props":3517,"children":3518},{"style":172},[3519],{"type":46,"value":205},{"type":40,"tag":97,"props":3521,"children":3522},{"style":125},[3523],{"type":46,"value":210},{"type":40,"tag":97,"props":3525,"children":3526},{"class":99,"line":503},[3527,3531,3535,3540,3545,3549,3553],{"type":40,"tag":97,"props":3528,"children":3529},{"style":131},[3530],{"type":46,"value":1863},{"type":40,"tag":97,"props":3532,"children":3533},{"style":172},[3534],{"type":46,"value":223},{"type":40,"tag":97,"props":3536,"children":3537},{"style":119},[3538],{"type":46,"value":3539},"remaining",{"type":40,"tag":97,"props":3541,"children":3542},{"style":125},[3543],{"type":46,"value":3544}," \u003C",{"type":40,"tag":97,"props":3546,"children":3547},{"style":450},[3548],{"type":46,"value":453},{"type":40,"tag":97,"props":3550,"children":3551},{"style":172},[3552],{"type":46,"value":458},{"type":40,"tag":97,"props":3554,"children":3555},{"style":125},[3556],{"type":46,"value":1312},{"type":40,"tag":97,"props":3558,"children":3559},{"class":99,"line":863},[3560,3564,3568,3572,3577,3581,3585,3589,3593,3597,3601,3605],{"type":40,"tag":97,"props":3561,"children":3562},{"style":131},[3563],{"type":46,"value":3207},{"type":40,"tag":97,"props":3565,"children":3566},{"style":119},[3567],{"type":46,"value":3480},{"type":40,"tag":97,"props":3569,"children":3570},{"style":125},[3571],{"type":46,"value":144},{"type":40,"tag":97,"props":3573,"children":3574},{"style":156},[3575],{"type":46,"value":3576},"incr",{"type":40,"tag":97,"props":3578,"children":3579},{"style":172},[3580],{"type":46,"value":164},{"type":40,"tag":97,"props":3582,"children":3583},{"style":125},[3584],{"type":46,"value":2994},{"type":40,"tag":97,"props":3586,"children":3587},{"style":485},[3588],{"type":46,"value":3502},{"type":40,"tag":97,"props":3590,"children":3591},{"style":125},[3592],{"type":46,"value":3004},{"type":40,"tag":97,"props":3594,"children":3595},{"style":119},[3596],{"type":46,"value":1657},{"type":40,"tag":97,"props":3598,"children":3599},{"style":125},[3600],{"type":46,"value":3515},{"type":40,"tag":97,"props":3602,"children":3603},{"style":172},[3604],{"type":46,"value":205},{"type":40,"tag":97,"props":3606,"children":3607},{"style":125},[3608],{"type":46,"value":210},{"type":40,"tag":97,"props":3610,"children":3611},{"class":99,"line":1315},[3612,3616,3620,3624,3628,3632,3636,3640,3644],{"type":40,"tag":97,"props":3613,"children":3614},{"style":131},[3615],{"type":46,"value":1438},{"type":40,"tag":97,"props":3617,"children":3618},{"style":125},[3619],{"type":46,"value":468},{"type":40,"tag":97,"props":3621,"children":3622},{"style":156},[3623],{"type":46,"value":473},{"type":40,"tag":97,"props":3625,"children":3626},{"style":172},[3627],{"type":46,"value":164},{"type":40,"tag":97,"props":3629,"children":3630},{"style":125},[3631],{"type":46,"value":482},{"type":40,"tag":97,"props":3633,"children":3634},{"style":485},[3635],{"type":46,"value":488},{"type":40,"tag":97,"props":3637,"children":3638},{"style":125},[3639],{"type":46,"value":482},{"type":40,"tag":97,"props":3641,"children":3642},{"style":172},[3643],{"type":46,"value":205},{"type":40,"tag":97,"props":3645,"children":3646},{"style":125},[3647],{"type":46,"value":210},{"type":40,"tag":97,"props":3649,"children":3650},{"class":99,"line":1350},[3651],{"type":40,"tag":97,"props":3652,"children":3653},{"style":125},[3654],{"type":46,"value":1456},{"type":40,"tag":97,"props":3656,"children":3657},{"class":99,"line":1423},[3658],{"type":40,"tag":97,"props":3659,"children":3660},{"style":125},[3661],{"type":46,"value":1465},{"type":40,"tag":73,"props":3663,"children":3665},{"id":3664},"lua-scripts-for-multi-step-atomic-operations",[3666],{"type":46,"value":3667},"Lua scripts for multi-step atomic operations",{"type":40,"tag":85,"props":3669,"children":3671},{"className":87,"code":3670,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: the whole script executes atomically in Redis\nconst CLAIM_COUPON = `\n  local used = redis.call('SISMEMBER', KEYS[1], ARGV[1])\n  if used == 1 then return 0 end\n  redis.call('SADD', KEYS[1], ARGV[1])\n  return 1\n`;\n\nasync function claimCoupon(couponId: string, userId: string): Promise\u003Cboolean> {\n  const result = await redis.eval(CLAIM_COUPON, 1, `coupon:${couponId}:used`, userId);\n  return result === 1;\n}\n",[3672],{"type":40,"tag":93,"props":3673,"children":3674},{"__ignoreMap":90},[3675,3683,3704,3712,3720,3728,3736,3747,3754,3832,3932,3956],{"type":40,"tag":97,"props":3676,"children":3677},{"class":99,"line":27},[3678],{"type":40,"tag":97,"props":3679,"children":3680},{"style":103},[3681],{"type":46,"value":3682},"\u002F\u002F SAFE: the whole script executes atomically in Redis\n",{"type":40,"tag":97,"props":3684,"children":3685},{"class":99,"line":109},[3686,3690,3695,3699],{"type":40,"tag":97,"props":3687,"children":3688},{"style":113},[3689],{"type":46,"value":116},{"type":40,"tag":97,"props":3691,"children":3692},{"style":119},[3693],{"type":46,"value":3694}," CLAIM_COUPON ",{"type":40,"tag":97,"props":3696,"children":3697},{"style":125},[3698],{"type":46,"value":128},{"type":40,"tag":97,"props":3700,"children":3701},{"style":125},[3702],{"type":46,"value":3703}," `\n",{"type":40,"tag":97,"props":3705,"children":3706},{"class":99,"line":23},[3707],{"type":40,"tag":97,"props":3708,"children":3709},{"style":485},[3710],{"type":46,"value":3711},"  local used = redis.call('SISMEMBER', KEYS[1], ARGV[1])\n",{"type":40,"tag":97,"props":3713,"children":3714},{"class":99,"line":503},[3715],{"type":40,"tag":97,"props":3716,"children":3717},{"style":485},[3718],{"type":46,"value":3719},"  if used == 1 then return 0 end\n",{"type":40,"tag":97,"props":3721,"children":3722},{"class":99,"line":863},[3723],{"type":40,"tag":97,"props":3724,"children":3725},{"style":485},[3726],{"type":46,"value":3727},"  redis.call('SADD', KEYS[1], ARGV[1])\n",{"type":40,"tag":97,"props":3729,"children":3730},{"class":99,"line":1315},[3731],{"type":40,"tag":97,"props":3732,"children":3733},{"style":485},[3734],{"type":46,"value":3735},"  return 1\n",{"type":40,"tag":97,"props":3737,"children":3738},{"class":99,"line":1350},[3739,3743],{"type":40,"tag":97,"props":3740,"children":3741},{"style":125},[3742],{"type":46,"value":2994},{"type":40,"tag":97,"props":3744,"children":3745},{"style":125},[3746],{"type":46,"value":210},{"type":40,"tag":97,"props":3748,"children":3749},{"class":99,"line":1423},[3750],{"type":40,"tag":97,"props":3751,"children":3752},{"emptyLinePlaceholder":1472},[3753],{"type":46,"value":1475},{"type":40,"tag":97,"props":3755,"children":3756},{"class":99,"line":1432},[3757,3761,3765,3770,3774,3779,3783,3787,3791,3796,3800,3804,3809,3814,3818,3823,3828],{"type":40,"tag":97,"props":3758,"children":3759},{"style":113},[3760],{"type":46,"value":1157},{"type":40,"tag":97,"props":3762,"children":3763},{"style":113},[3764],{"type":46,"value":1162},{"type":40,"tag":97,"props":3766,"children":3767},{"style":156},[3768],{"type":46,"value":3769}," claimCoupon",{"type":40,"tag":97,"props":3771,"children":3772},{"style":125},[3773],{"type":46,"value":164},{"type":40,"tag":97,"props":3775,"children":3776},{"style":1174},[3777],{"type":46,"value":3778},"couponId",{"type":40,"tag":97,"props":3780,"children":3781},{"style":125},[3782],{"type":46,"value":180},{"type":40,"tag":97,"props":3784,"children":3785},{"style":1184},[3786],{"type":46,"value":1187},{"type":40,"tag":97,"props":3788,"children":3789},{"style":125},[3790],{"type":46,"value":1576},{"type":40,"tag":97,"props":3792,"children":3793},{"style":1174},[3794],{"type":46,"value":3795}," userId",{"type":40,"tag":97,"props":3797,"children":3798},{"style":125},[3799],{"type":46,"value":180},{"type":40,"tag":97,"props":3801,"children":3802},{"style":1184},[3803],{"type":46,"value":1187},{"type":40,"tag":97,"props":3805,"children":3806},{"style":125},[3807],{"type":46,"value":3808},"):",{"type":40,"tag":97,"props":3810,"children":3811},{"style":1184},[3812],{"type":46,"value":3813}," Promise",{"type":40,"tag":97,"props":3815,"children":3816},{"style":125},[3817],{"type":46,"value":2478},{"type":40,"tag":97,"props":3819,"children":3820},{"style":1184},[3821],{"type":46,"value":3822},"boolean",{"type":40,"tag":97,"props":3824,"children":3825},{"style":125},[3826],{"type":46,"value":3827},">",{"type":40,"tag":97,"props":3829,"children":3830},{"style":125},[3831],{"type":46,"value":1196},{"type":40,"tag":97,"props":3833,"children":3834},{"class":99,"line":1450},[3835,3839,3843,3847,3851,3855,3859,3864,3868,3873,3877,3881,3885,3890,3895,3899,3903,3907,3912,3916,3920,3924,3928],{"type":40,"tag":97,"props":3836,"children":3837},{"style":113},[3838],{"type":46,"value":1681},{"type":40,"tag":97,"props":3840,"children":3841},{"style":119},[3842],{"type":46,"value":1686},{"type":40,"tag":97,"props":3844,"children":3845},{"style":125},[3846],{"type":46,"value":1691},{"type":40,"tag":97,"props":3848,"children":3849},{"style":131},[3850],{"type":46,"value":134},{"type":40,"tag":97,"props":3852,"children":3853},{"style":119},[3854],{"type":46,"value":3480},{"type":40,"tag":97,"props":3856,"children":3857},{"style":125},[3858],{"type":46,"value":144},{"type":40,"tag":97,"props":3860,"children":3861},{"style":156},[3862],{"type":46,"value":3863},"eval",{"type":40,"tag":97,"props":3865,"children":3866},{"style":172},[3867],{"type":46,"value":164},{"type":40,"tag":97,"props":3869,"children":3870},{"style":119},[3871],{"type":46,"value":3872},"CLAIM_COUPON",{"type":40,"tag":97,"props":3874,"children":3875},{"style":125},[3876],{"type":46,"value":1576},{"type":40,"tag":97,"props":3878,"children":3879},{"style":450},[3880],{"type":46,"value":611},{"type":40,"tag":97,"props":3882,"children":3883},{"style":125},[3884],{"type":46,"value":1576},{"type":40,"tag":97,"props":3886,"children":3887},{"style":125},[3888],{"type":46,"value":3889}," `",{"type":40,"tag":97,"props":3891,"children":3892},{"style":485},[3893],{"type":46,"value":3894},"coupon:",{"type":40,"tag":97,"props":3896,"children":3897},{"style":125},[3898],{"type":46,"value":3004},{"type":40,"tag":97,"props":3900,"children":3901},{"style":119},[3902],{"type":46,"value":3778},{"type":40,"tag":97,"props":3904,"children":3905},{"style":125},[3906],{"type":46,"value":195},{"type":40,"tag":97,"props":3908,"children":3909},{"style":485},[3910],{"type":46,"value":3911},":used",{"type":40,"tag":97,"props":3913,"children":3914},{"style":125},[3915],{"type":46,"value":2994},{"type":40,"tag":97,"props":3917,"children":3918},{"style":125},[3919],{"type":46,"value":1576},{"type":40,"tag":97,"props":3921,"children":3922},{"style":119},[3923],{"type":46,"value":3795},{"type":40,"tag":97,"props":3925,"children":3926},{"style":172},[3927],{"type":46,"value":205},{"type":40,"tag":97,"props":3929,"children":3930},{"style":125},[3931],{"type":46,"value":210},{"type":40,"tag":97,"props":3933,"children":3934},{"class":99,"line":1459},[3935,3940,3944,3948,3952],{"type":40,"tag":97,"props":3936,"children":3937},{"style":131},[3938],{"type":46,"value":3939},"  return",{"type":40,"tag":97,"props":3941,"children":3942},{"style":119},[3943],{"type":46,"value":1686},{"type":40,"tag":97,"props":3945,"children":3946},{"style":125},[3947],{"type":46,"value":1886},{"type":40,"tag":97,"props":3949,"children":3950},{"style":450},[3951],{"type":46,"value":611},{"type":40,"tag":97,"props":3953,"children":3954},{"style":125},[3955],{"type":46,"value":210},{"type":40,"tag":97,"props":3957,"children":3958},{"class":99,"line":1468},[3959],{"type":40,"tag":97,"props":3960,"children":3961},{"style":125},[3962],{"type":46,"value":1465},{"type":40,"tag":73,"props":3964,"children":3966},{"id":3965},"set-nx-for-simple-locks",[3967],{"type":46,"value":3968},"SET NX for simple locks",{"type":40,"tag":85,"props":3970,"children":3972},{"className":87,"code":3971,"language":89,"meta":90,"style":90},"\u002F\u002F SAFE: atomic set-if-not-exists with auto-expiry to prevent deadlocks\nasync function acquireLock(resource: string, ttlMs: number): Promise\u003Cstring | null> {\n  const token = crypto.randomUUID();\n  const acquired = await redis.set(`lock:${resource}`, token, \"PX\", ttlMs, \"NX\");\n  return acquired === \"OK\" ? token : null;\n}\n\n\u002F\u002F Release with Lua so you only release YOUR lock\nconst RELEASE_LOCK = `\n  if redis.call('GET', KEYS[1]) == ARGV[1] then\n    return redis.call('DEL', KEYS[1])\n  end\n  return 0\n`;\n\nasync function releaseLock(resource: string, token: string) {\n  await redis.eval(RELEASE_LOCK, 1, `lock:${resource}`, token);\n}\n",[3973],{"type":40,"tag":93,"props":3974,"children":3975},{"__ignoreMap":90},[3976,3984,4070,4109,4225,4272,4279,4286,4294,4314,4322,4330,4338,4346,4357,4365,4422,4499],{"type":40,"tag":97,"props":3977,"children":3978},{"class":99,"line":27},[3979],{"type":40,"tag":97,"props":3980,"children":3981},{"style":103},[3982],{"type":46,"value":3983},"\u002F\u002F SAFE: atomic set-if-not-exists with auto-expiry to prevent deadlocks\n",{"type":40,"tag":97,"props":3985,"children":3986},{"class":99,"line":109},[3987,3991,3995,4000,4004,4009,4013,4017,4021,4026,4030,4035,4039,4043,4047,4052,4057,4062,4066],{"type":40,"tag":97,"props":3988,"children":3989},{"style":113},[3990],{"type":46,"value":1157},{"type":40,"tag":97,"props":3992,"children":3993},{"style":113},[3994],{"type":46,"value":1162},{"type":40,"tag":97,"props":3996,"children":3997},{"style":156},[3998],{"type":46,"value":3999}," acquireLock",{"type":40,"tag":97,"props":4001,"children":4002},{"style":125},[4003],{"type":46,"value":164},{"type":40,"tag":97,"props":4005,"children":4006},{"style":1174},[4007],{"type":46,"value":4008},"resource",{"type":40,"tag":97,"props":4010,"children":4011},{"style":125},[4012],{"type":46,"value":180},{"type":40,"tag":97,"props":4014,"children":4015},{"style":1184},[4016],{"type":46,"value":1187},{"type":40,"tag":97,"props":4018,"children":4019},{"style":125},[4020],{"type":46,"value":1576},{"type":40,"tag":97,"props":4022,"children":4023},{"style":1174},[4024],{"type":46,"value":4025}," ttlMs",{"type":40,"tag":97,"props":4027,"children":4028},{"style":125},[4029],{"type":46,"value":180},{"type":40,"tag":97,"props":4031,"children":4032},{"style":1184},[4033],{"type":46,"value":4034}," number",{"type":40,"tag":97,"props":4036,"children":4037},{"style":125},[4038],{"type":46,"value":3808},{"type":40,"tag":97,"props":4040,"children":4041},{"style":1184},[4042],{"type":46,"value":3813},{"type":40,"tag":97,"props":4044,"children":4045},{"style":125},[4046],{"type":46,"value":2478},{"type":40,"tag":97,"props":4048,"children":4049},{"style":1184},[4050],{"type":46,"value":4051},"string",{"type":40,"tag":97,"props":4053,"children":4054},{"style":125},[4055],{"type":46,"value":4056}," |",{"type":40,"tag":97,"props":4058,"children":4059},{"style":1184},[4060],{"type":46,"value":4061}," null",{"type":40,"tag":97,"props":4063,"children":4064},{"style":125},[4065],{"type":46,"value":3827},{"type":40,"tag":97,"props":4067,"children":4068},{"style":125},[4069],{"type":46,"value":1196},{"type":40,"tag":97,"props":4071,"children":4072},{"class":99,"line":23},[4073,4077,4082,4086,4091,4095,4100,4105],{"type":40,"tag":97,"props":4074,"children":4075},{"style":113},[4076],{"type":46,"value":1681},{"type":40,"tag":97,"props":4078,"children":4079},{"style":119},[4080],{"type":46,"value":4081}," token",{"type":40,"tag":97,"props":4083,"children":4084},{"style":125},[4085],{"type":46,"value":1691},{"type":40,"tag":97,"props":4087,"children":4088},{"style":119},[4089],{"type":46,"value":4090}," crypto",{"type":40,"tag":97,"props":4092,"children":4093},{"style":125},[4094],{"type":46,"value":144},{"type":40,"tag":97,"props":4096,"children":4097},{"style":156},[4098],{"type":46,"value":4099},"randomUUID",{"type":40,"tag":97,"props":4101,"children":4102},{"style":172},[4103],{"type":46,"value":4104},"()",{"type":40,"tag":97,"props":4106,"children":4107},{"style":125},[4108],{"type":46,"value":210},{"type":40,"tag":97,"props":4110,"children":4111},{"class":99,"line":503},[4112,4116,4121,4125,4129,4133,4137,4142,4146,4150,4155,4159,4163,4167,4171,4175,4179,4183,4188,4192,4196,4200,4204,4208,4213,4217,4221],{"type":40,"tag":97,"props":4113,"children":4114},{"style":113},[4115],{"type":46,"value":1681},{"type":40,"tag":97,"props":4117,"children":4118},{"style":119},[4119],{"type":46,"value":4120}," acquired",{"type":40,"tag":97,"props":4122,"children":4123},{"style":125},[4124],{"type":46,"value":1691},{"type":40,"tag":97,"props":4126,"children":4127},{"style":131},[4128],{"type":46,"value":134},{"type":40,"tag":97,"props":4130,"children":4131},{"style":119},[4132],{"type":46,"value":3480},{"type":40,"tag":97,"props":4134,"children":4135},{"style":125},[4136],{"type":46,"value":144},{"type":40,"tag":97,"props":4138,"children":4139},{"style":156},[4140],{"type":46,"value":4141},"set",{"type":40,"tag":97,"props":4143,"children":4144},{"style":172},[4145],{"type":46,"value":164},{"type":40,"tag":97,"props":4147,"children":4148},{"style":125},[4149],{"type":46,"value":2994},{"type":40,"tag":97,"props":4151,"children":4152},{"style":485},[4153],{"type":46,"value":4154},"lock:",{"type":40,"tag":97,"props":4156,"children":4157},{"style":125},[4158],{"type":46,"value":3004},{"type":40,"tag":97,"props":4160,"children":4161},{"style":119},[4162],{"type":46,"value":4008},{"type":40,"tag":97,"props":4164,"children":4165},{"style":125},[4166],{"type":46,"value":3515},{"type":40,"tag":97,"props":4168,"children":4169},{"style":125},[4170],{"type":46,"value":1576},{"type":40,"tag":97,"props":4172,"children":4173},{"style":119},[4174],{"type":46,"value":4081},{"type":40,"tag":97,"props":4176,"children":4177},{"style":125},[4178],{"type":46,"value":1576},{"type":40,"tag":97,"props":4180,"children":4181},{"style":125},[4182],{"type":46,"value":774},{"type":40,"tag":97,"props":4184,"children":4185},{"style":485},[4186],{"type":46,"value":4187},"PX",{"type":40,"tag":97,"props":4189,"children":4190},{"style":125},[4191],{"type":46,"value":482},{"type":40,"tag":97,"props":4193,"children":4194},{"style":125},[4195],{"type":46,"value":1576},{"type":40,"tag":97,"props":4197,"children":4198},{"style":119},[4199],{"type":46,"value":4025},{"type":40,"tag":97,"props":4201,"children":4202},{"style":125},[4203],{"type":46,"value":1576},{"type":40,"tag":97,"props":4205,"children":4206},{"style":125},[4207],{"type":46,"value":774},{"type":40,"tag":97,"props":4209,"children":4210},{"style":485},[4211],{"type":46,"value":4212},"NX",{"type":40,"tag":97,"props":4214,"children":4215},{"style":125},[4216],{"type":46,"value":482},{"type":40,"tag":97,"props":4218,"children":4219},{"style":172},[4220],{"type":46,"value":205},{"type":40,"tag":97,"props":4222,"children":4223},{"style":125},[4224],{"type":46,"value":210},{"type":40,"tag":97,"props":4226,"children":4227},{"class":99,"line":863},[4228,4232,4236,4240,4244,4249,4253,4258,4262,4267],{"type":40,"tag":97,"props":4229,"children":4230},{"style":131},[4231],{"type":46,"value":3939},{"type":40,"tag":97,"props":4233,"children":4234},{"style":119},[4235],{"type":46,"value":4120},{"type":40,"tag":97,"props":4237,"children":4238},{"style":125},[4239],{"type":46,"value":1886},{"type":40,"tag":97,"props":4241,"children":4242},{"style":125},[4243],{"type":46,"value":774},{"type":40,"tag":97,"props":4245,"children":4246},{"style":485},[4247],{"type":46,"value":4248},"OK",{"type":40,"tag":97,"props":4250,"children":4251},{"style":125},[4252],{"type":46,"value":482},{"type":40,"tag":97,"props":4254,"children":4255},{"style":125},[4256],{"type":46,"value":4257}," ?",{"type":40,"tag":97,"props":4259,"children":4260},{"style":119},[4261],{"type":46,"value":4081},{"type":40,"tag":97,"props":4263,"children":4264},{"style":125},[4265],{"type":46,"value":4266}," :",{"type":40,"tag":97,"props":4268,"children":4269},{"style":125},[4270],{"type":46,"value":4271}," null;\n",{"type":40,"tag":97,"props":4273,"children":4274},{"class":99,"line":1315},[4275],{"type":40,"tag":97,"props":4276,"children":4277},{"style":125},[4278],{"type":46,"value":1465},{"type":40,"tag":97,"props":4280,"children":4281},{"class":99,"line":1350},[4282],{"type":40,"tag":97,"props":4283,"children":4284},{"emptyLinePlaceholder":1472},[4285],{"type":46,"value":1475},{"type":40,"tag":97,"props":4287,"children":4288},{"class":99,"line":1423},[4289],{"type":40,"tag":97,"props":4290,"children":4291},{"style":103},[4292],{"type":46,"value":4293},"\u002F\u002F Release with Lua so you only release YOUR lock\n",{"type":40,"tag":97,"props":4295,"children":4296},{"class":99,"line":1432},[4297,4301,4306,4310],{"type":40,"tag":97,"props":4298,"children":4299},{"style":113},[4300],{"type":46,"value":116},{"type":40,"tag":97,"props":4302,"children":4303},{"style":119},[4304],{"type":46,"value":4305}," RELEASE_LOCK ",{"type":40,"tag":97,"props":4307,"children":4308},{"style":125},[4309],{"type":46,"value":128},{"type":40,"tag":97,"props":4311,"children":4312},{"style":125},[4313],{"type":46,"value":3703},{"type":40,"tag":97,"props":4315,"children":4316},{"class":99,"line":1450},[4317],{"type":40,"tag":97,"props":4318,"children":4319},{"style":485},[4320],{"type":46,"value":4321},"  if redis.call('GET', KEYS[1]) == ARGV[1] then\n",{"type":40,"tag":97,"props":4323,"children":4324},{"class":99,"line":1459},[4325],{"type":40,"tag":97,"props":4326,"children":4327},{"style":485},[4328],{"type":46,"value":4329},"    return redis.call('DEL', KEYS[1])\n",{"type":40,"tag":97,"props":4331,"children":4332},{"class":99,"line":1468},[4333],{"type":40,"tag":97,"props":4334,"children":4335},{"style":485},[4336],{"type":46,"value":4337},"  end\n",{"type":40,"tag":97,"props":4339,"children":4340},{"class":99,"line":1478},[4341],{"type":40,"tag":97,"props":4342,"children":4343},{"style":485},[4344],{"type":46,"value":4345},"  return 0\n",{"type":40,"tag":97,"props":4347,"children":4348},{"class":99,"line":1487},[4349,4353],{"type":40,"tag":97,"props":4350,"children":4351},{"style":125},[4352],{"type":46,"value":2994},{"type":40,"tag":97,"props":4354,"children":4355},{"style":125},[4356],{"type":46,"value":210},{"type":40,"tag":97,"props":4358,"children":4360},{"class":99,"line":4359},15,[4361],{"type":40,"tag":97,"props":4362,"children":4363},{"emptyLinePlaceholder":1472},[4364],{"type":46,"value":1475},{"type":40,"tag":97,"props":4366,"children":4368},{"class":99,"line":4367},16,[4369,4373,4377,4382,4386,4390,4394,4398,4402,4406,4410,4414,4418],{"type":40,"tag":97,"props":4370,"children":4371},{"style":113},[4372],{"type":46,"value":1157},{"type":40,"tag":97,"props":4374,"children":4375},{"style":113},[4376],{"type":46,"value":1162},{"type":40,"tag":97,"props":4378,"children":4379},{"style":156},[4380],{"type":46,"value":4381}," releaseLock",{"type":40,"tag":97,"props":4383,"children":4384},{"style":125},[4385],{"type":46,"value":164},{"type":40,"tag":97,"props":4387,"children":4388},{"style":1174},[4389],{"type":46,"value":4008},{"type":40,"tag":97,"props":4391,"children":4392},{"style":125},[4393],{"type":46,"value":180},{"type":40,"tag":97,"props":4395,"children":4396},{"style":1184},[4397],{"type":46,"value":1187},{"type":40,"tag":97,"props":4399,"children":4400},{"style":125},[4401],{"type":46,"value":1576},{"type":40,"tag":97,"props":4403,"children":4404},{"style":1174},[4405],{"type":46,"value":4081},{"type":40,"tag":97,"props":4407,"children":4408},{"style":125},[4409],{"type":46,"value":180},{"type":40,"tag":97,"props":4411,"children":4412},{"style":1184},[4413],{"type":46,"value":1187},{"type":40,"tag":97,"props":4415,"children":4416},{"style":125},[4417],{"type":46,"value":205},{"type":40,"tag":97,"props":4419,"children":4420},{"style":125},[4421],{"type":46,"value":1196},{"type":40,"tag":97,"props":4423,"children":4425},{"class":99,"line":4424},17,[4426,4430,4434,4438,4442,4446,4451,4455,4459,4463,4467,4471,4475,4479,4483,4487,4491,4495],{"type":40,"tag":97,"props":4427,"children":4428},{"style":131},[4429],{"type":46,"value":2250},{"type":40,"tag":97,"props":4431,"children":4432},{"style":119},[4433],{"type":46,"value":3480},{"type":40,"tag":97,"props":4435,"children":4436},{"style":125},[4437],{"type":46,"value":144},{"type":40,"tag":97,"props":4439,"children":4440},{"style":156},[4441],{"type":46,"value":3863},{"type":40,"tag":97,"props":4443,"children":4444},{"style":172},[4445],{"type":46,"value":164},{"type":40,"tag":97,"props":4447,"children":4448},{"style":119},[4449],{"type":46,"value":4450},"RELEASE_LOCK",{"type":40,"tag":97,"props":4452,"children":4453},{"style":125},[4454],{"type":46,"value":1576},{"type":40,"tag":97,"props":4456,"children":4457},{"style":450},[4458],{"type":46,"value":611},{"type":40,"tag":97,"props":4460,"children":4461},{"style":125},[4462],{"type":46,"value":1576},{"type":40,"tag":97,"props":4464,"children":4465},{"style":125},[4466],{"type":46,"value":3889},{"type":40,"tag":97,"props":4468,"children":4469},{"style":485},[4470],{"type":46,"value":4154},{"type":40,"tag":97,"props":4472,"children":4473},{"style":125},[4474],{"type":46,"value":3004},{"type":40,"tag":97,"props":4476,"children":4477},{"style":119},[4478],{"type":46,"value":4008},{"type":40,"tag":97,"props":4480,"children":4481},{"style":125},[4482],{"type":46,"value":3515},{"type":40,"tag":97,"props":4484,"children":4485},{"style":125},[4486],{"type":46,"value":1576},{"type":40,"tag":97,"props":4488,"children":4489},{"style":119},[4490],{"type":46,"value":4081},{"type":40,"tag":97,"props":4492,"children":4493},{"style":172},[4494],{"type":46,"value":205},{"type":40,"tag":97,"props":4496,"children":4497},{"style":125},[4498],{"type":46,"value":210},{"type":40,"tag":97,"props":4500,"children":4502},{"class":99,"line":4501},18,[4503],{"type":40,"tag":97,"props":4504,"children":4505},{"style":125},[4506],{"type":46,"value":1465},{"type":40,"tag":61,"props":4508,"children":4510},{"id":4509},"distributed-locks-and-redlock",[4511],{"type":46,"value":4512},"Distributed Locks and Redlock",{"type":40,"tag":49,"props":4514,"children":4515},{},[4516,4518,4523],{"type":46,"value":4517},"When you need mutual exclusion across processes or servers and ",{"type":40,"tag":93,"props":4519,"children":4521},{"className":4520},[],[4522],{"type":46,"value":3382},{"type":46,"value":4524}," won't work (e.g., the critical section touches non-database resources), you may need a distributed lock.",{"type":40,"tag":49,"props":4526,"children":4527},{},[4528,4533,4535,4541],{"type":40,"tag":55,"props":4529,"children":4530},{},[4531],{"type":46,"value":4532},"Single-instance Redis (usually sufficient):",{"type":46,"value":4534}," ",{"type":40,"tag":93,"props":4536,"children":4538},{"className":4537},[],[4539],{"type":46,"value":4540},"SET NX PX",{"type":46,"value":4542}," (above) is good enough for most apps. Failure mode is well-understood: if Redis dies the lock is lost and two processes may enter the critical section. Acceptable when the lock is a best-effort guard, not a safety-critical mutex.",{"type":40,"tag":49,"props":4544,"children":4545},{},[4546,4551],{"type":40,"tag":55,"props":4547,"children":4548},{},[4549],{"type":46,"value":4550},"Redlock (when single-instance isn't enough):",{"type":46,"value":4552}," uses N independent Redis instances (typically 5); a client holds the lock if it acquires a majority (N\u002F2 + 1) within a time bound.",{"type":40,"tag":85,"props":4554,"children":4556},{"className":87,"code":4555,"language":89,"meta":90,"style":90},"import { Redlock } from \"redlock\";\n\nconst redlock = new Redlock([redis1, redis2, redis3, redis4, redis5], { retryCount: 3, retryDelay: 200 });\n\nasync function processExclusively(resourceId: string) {\n  const lock = await redlock.acquire([`lock:${resourceId}`], 30_000);\n  try {\n    await doExclusiveWork(resourceId);\n  } finally {\n    await lock.release();\n  }\n}\n",[4557],{"type":40,"tag":93,"props":4558,"children":4559},{"__ignoreMap":90},[4560,4603,4610,4727,4734,4775,4856,4867,4895,4911,4939,4946],{"type":40,"tag":97,"props":4561,"children":4562},{"class":99,"line":27},[4563,4568,4572,4577,4581,4586,4590,4595,4599],{"type":40,"tag":97,"props":4564,"children":4565},{"style":131},[4566],{"type":46,"value":4567},"import",{"type":40,"tag":97,"props":4569,"children":4570},{"style":125},[4571],{"type":46,"value":185},{"type":40,"tag":97,"props":4573,"children":4574},{"style":119},[4575],{"type":46,"value":4576}," Redlock",{"type":40,"tag":97,"props":4578,"children":4579},{"style":125},[4580],{"type":46,"value":200},{"type":40,"tag":97,"props":4582,"children":4583},{"style":131},[4584],{"type":46,"value":4585}," from",{"type":40,"tag":97,"props":4587,"children":4588},{"style":125},[4589],{"type":46,"value":774},{"type":40,"tag":97,"props":4591,"children":4592},{"style":485},[4593],{"type":46,"value":4594},"redlock",{"type":40,"tag":97,"props":4596,"children":4597},{"style":125},[4598],{"type":46,"value":482},{"type":40,"tag":97,"props":4600,"children":4601},{"style":125},[4602],{"type":46,"value":210},{"type":40,"tag":97,"props":4604,"children":4605},{"class":99,"line":109},[4606],{"type":40,"tag":97,"props":4607,"children":4608},{"emptyLinePlaceholder":1472},[4609],{"type":46,"value":1475},{"type":40,"tag":97,"props":4611,"children":4612},{"class":99,"line":23},[4613,4617,4622,4626,4630,4634,4639,4643,4648,4652,4657,4661,4666,4670,4675,4679,4683,4688,4692,4697,4701,4706,4710,4715,4719,4723],{"type":40,"tag":97,"props":4614,"children":4615},{"style":113},[4616],{"type":46,"value":116},{"type":40,"tag":97,"props":4618,"children":4619},{"style":119},[4620],{"type":46,"value":4621}," redlock ",{"type":40,"tag":97,"props":4623,"children":4624},{"style":125},[4625],{"type":46,"value":128},{"type":40,"tag":97,"props":4627,"children":4628},{"style":125},[4629],{"type":46,"value":468},{"type":40,"tag":97,"props":4631,"children":4632},{"style":156},[4633],{"type":46,"value":4576},{"type":40,"tag":97,"props":4635,"children":4636},{"style":119},[4637],{"type":46,"value":4638},"([redis1",{"type":40,"tag":97,"props":4640,"children":4641},{"style":125},[4642],{"type":46,"value":1576},{"type":40,"tag":97,"props":4644,"children":4645},{"style":119},[4646],{"type":46,"value":4647}," redis2",{"type":40,"tag":97,"props":4649,"children":4650},{"style":125},[4651],{"type":46,"value":1576},{"type":40,"tag":97,"props":4653,"children":4654},{"style":119},[4655],{"type":46,"value":4656}," redis3",{"type":40,"tag":97,"props":4658,"children":4659},{"style":125},[4660],{"type":46,"value":1576},{"type":40,"tag":97,"props":4662,"children":4663},{"style":119},[4664],{"type":46,"value":4665}," redis4",{"type":40,"tag":97,"props":4667,"children":4668},{"style":125},[4669],{"type":46,"value":1576},{"type":40,"tag":97,"props":4671,"children":4672},{"style":119},[4673],{"type":46,"value":4674}," redis5]",{"type":40,"tag":97,"props":4676,"children":4677},{"style":125},[4678],{"type":46,"value":1576},{"type":40,"tag":97,"props":4680,"children":4681},{"style":125},[4682],{"type":46,"value":185},{"type":40,"tag":97,"props":4684,"children":4685},{"style":172},[4686],{"type":46,"value":4687}," retryCount",{"type":40,"tag":97,"props":4689,"children":4690},{"style":125},[4691],{"type":46,"value":180},{"type":40,"tag":97,"props":4693,"children":4694},{"style":450},[4695],{"type":46,"value":4696}," 3",{"type":40,"tag":97,"props":4698,"children":4699},{"style":125},[4700],{"type":46,"value":1576},{"type":40,"tag":97,"props":4702,"children":4703},{"style":172},[4704],{"type":46,"value":4705}," retryDelay",{"type":40,"tag":97,"props":4707,"children":4708},{"style":125},[4709],{"type":46,"value":180},{"type":40,"tag":97,"props":4711,"children":4712},{"style":450},[4713],{"type":46,"value":4714}," 200",{"type":40,"tag":97,"props":4716,"children":4717},{"style":125},[4718],{"type":46,"value":200},{"type":40,"tag":97,"props":4720,"children":4721},{"style":119},[4722],{"type":46,"value":205},{"type":40,"tag":97,"props":4724,"children":4725},{"style":125},[4726],{"type":46,"value":210},{"type":40,"tag":97,"props":4728,"children":4729},{"class":99,"line":503},[4730],{"type":40,"tag":97,"props":4731,"children":4732},{"emptyLinePlaceholder":1472},[4733],{"type":46,"value":1475},{"type":40,"tag":97,"props":4735,"children":4736},{"class":99,"line":863},[4737,4741,4745,4750,4754,4759,4763,4767,4771],{"type":40,"tag":97,"props":4738,"children":4739},{"style":113},[4740],{"type":46,"value":1157},{"type":40,"tag":97,"props":4742,"children":4743},{"style":113},[4744],{"type":46,"value":1162},{"type":40,"tag":97,"props":4746,"children":4747},{"style":156},[4748],{"type":46,"value":4749}," processExclusively",{"type":40,"tag":97,"props":4751,"children":4752},{"style":125},[4753],{"type":46,"value":164},{"type":40,"tag":97,"props":4755,"children":4756},{"style":1174},[4757],{"type":46,"value":4758},"resourceId",{"type":40,"tag":97,"props":4760,"children":4761},{"style":125},[4762],{"type":46,"value":180},{"type":40,"tag":97,"props":4764,"children":4765},{"style":1184},[4766],{"type":46,"value":1187},{"type":40,"tag":97,"props":4768,"children":4769},{"style":125},[4770],{"type":46,"value":205},{"type":40,"tag":97,"props":4772,"children":4773},{"style":125},[4774],{"type":46,"value":1196},{"type":40,"tag":97,"props":4776,"children":4777},{"class":99,"line":1315},[4778,4782,4787,4791,4795,4800,4804,4809,4814,4818,4822,4826,4830,4834,4839,4843,4848,4852],{"type":40,"tag":97,"props":4779,"children":4780},{"style":113},[4781],{"type":46,"value":1681},{"type":40,"tag":97,"props":4783,"children":4784},{"style":119},[4785],{"type":46,"value":4786}," lock",{"type":40,"tag":97,"props":4788,"children":4789},{"style":125},[4790],{"type":46,"value":1691},{"type":40,"tag":97,"props":4792,"children":4793},{"style":131},[4794],{"type":46,"value":134},{"type":40,"tag":97,"props":4796,"children":4797},{"style":119},[4798],{"type":46,"value":4799}," redlock",{"type":40,"tag":97,"props":4801,"children":4802},{"style":125},[4803],{"type":46,"value":144},{"type":40,"tag":97,"props":4805,"children":4806},{"style":156},[4807],{"type":46,"value":4808},"acquire",{"type":40,"tag":97,"props":4810,"children":4811},{"style":172},[4812],{"type":46,"value":4813},"([",{"type":40,"tag":97,"props":4815,"children":4816},{"style":125},[4817],{"type":46,"value":2994},{"type":40,"tag":97,"props":4819,"children":4820},{"style":485},[4821],{"type":46,"value":4154},{"type":40,"tag":97,"props":4823,"children":4824},{"style":125},[4825],{"type":46,"value":3004},{"type":40,"tag":97,"props":4827,"children":4828},{"style":119},[4829],{"type":46,"value":4758},{"type":40,"tag":97,"props":4831,"children":4832},{"style":125},[4833],{"type":46,"value":3515},{"type":40,"tag":97,"props":4835,"children":4836},{"style":172},[4837],{"type":46,"value":4838},"]",{"type":40,"tag":97,"props":4840,"children":4841},{"style":125},[4842],{"type":46,"value":1576},{"type":40,"tag":97,"props":4844,"children":4845},{"style":450},[4846],{"type":46,"value":4847}," 30_000",{"type":40,"tag":97,"props":4849,"children":4850},{"style":172},[4851],{"type":46,"value":205},{"type":40,"tag":97,"props":4853,"children":4854},{"style":125},[4855],{"type":46,"value":210},{"type":40,"tag":97,"props":4857,"children":4858},{"class":99,"line":1350},[4859,4863],{"type":40,"tag":97,"props":4860,"children":4861},{"style":131},[4862],{"type":46,"value":1204},{"type":40,"tag":97,"props":4864,"children":4865},{"style":125},[4866],{"type":46,"value":1196},{"type":40,"tag":97,"props":4868,"children":4869},{"class":99,"line":1423},[4870,4874,4879,4883,4887,4891],{"type":40,"tag":97,"props":4871,"children":4872},{"style":131},[4873],{"type":46,"value":3207},{"type":40,"tag":97,"props":4875,"children":4876},{"style":156},[4877],{"type":46,"value":4878}," doExclusiveWork",{"type":40,"tag":97,"props":4880,"children":4881},{"style":172},[4882],{"type":46,"value":164},{"type":40,"tag":97,"props":4884,"children":4885},{"style":119},[4886],{"type":46,"value":4758},{"type":40,"tag":97,"props":4888,"children":4889},{"style":172},[4890],{"type":46,"value":205},{"type":40,"tag":97,"props":4892,"children":4893},{"style":125},[4894],{"type":46,"value":210},{"type":40,"tag":97,"props":4896,"children":4897},{"class":99,"line":1432},[4898,4902,4907],{"type":40,"tag":97,"props":4899,"children":4900},{"style":125},[4901],{"type":46,"value":1289},{"type":40,"tag":97,"props":4903,"children":4904},{"style":131},[4905],{"type":46,"value":4906}," finally",{"type":40,"tag":97,"props":4908,"children":4909},{"style":125},[4910],{"type":46,"value":1196},{"type":40,"tag":97,"props":4912,"children":4913},{"class":99,"line":1450},[4914,4918,4922,4926,4931,4935],{"type":40,"tag":97,"props":4915,"children":4916},{"style":131},[4917],{"type":46,"value":3207},{"type":40,"tag":97,"props":4919,"children":4920},{"style":119},[4921],{"type":46,"value":4786},{"type":40,"tag":97,"props":4923,"children":4924},{"style":125},[4925],{"type":46,"value":144},{"type":40,"tag":97,"props":4927,"children":4928},{"style":156},[4929],{"type":46,"value":4930},"release",{"type":40,"tag":97,"props":4932,"children":4933},{"style":172},[4934],{"type":46,"value":4104},{"type":40,"tag":97,"props":4936,"children":4937},{"style":125},[4938],{"type":46,"value":210},{"type":40,"tag":97,"props":4940,"children":4941},{"class":99,"line":1459},[4942],{"type":40,"tag":97,"props":4943,"children":4944},{"style":125},[4945],{"type":46,"value":1456},{"type":40,"tag":97,"props":4947,"children":4948},{"class":99,"line":1468},[4949],{"type":40,"tag":97,"props":4950,"children":4951},{"style":125},[4952],{"type":46,"value":1465},{"type":40,"tag":73,"props":4954,"children":4956},{"id":4955},"when-to-use-what",[4957],{"type":46,"value":4958},"When to use what",{"type":40,"tag":4960,"props":4961,"children":4962},"table",{},[4963,4987],{"type":40,"tag":4964,"props":4965,"children":4966},"thead",{},[4967],{"type":40,"tag":4968,"props":4969,"children":4970},"tr",{},[4971,4977,4982],{"type":40,"tag":4972,"props":4973,"children":4974},"th",{},[4975],{"type":46,"value":4976},"Approach",{"type":40,"tag":4972,"props":4978,"children":4979},{},[4980],{"type":46,"value":4981},"Use when",{"type":40,"tag":4972,"props":4983,"children":4984},{},[4985],{"type":46,"value":4986},"Tradeoff",{"type":40,"tag":4988,"props":4989,"children":4990},"tbody",{},[4991,5015,5038,5056],{"type":40,"tag":4968,"props":4992,"children":4993},{},[4994,5005,5010],{"type":40,"tag":4995,"props":4996,"children":4997},"td",{},[4998,5000],{"type":46,"value":4999},"Database ",{"type":40,"tag":93,"props":5001,"children":5003},{"className":5002},[],[5004],{"type":46,"value":3382},{"type":40,"tag":4995,"props":5006,"children":5007},{},[5008],{"type":46,"value":5009},"Critical section is database operations",{"type":40,"tag":4995,"props":5011,"children":5012},{},[5013],{"type":46,"value":5014},"Serializes access, holds DB connection",{"type":40,"tag":4968,"props":5016,"children":5017},{},[5018,5028,5033],{"type":40,"tag":4995,"props":5019,"children":5020},{},[5021,5023],{"type":46,"value":5022},"Single Redis ",{"type":40,"tag":93,"props":5024,"children":5026},{"className":5025},[],[5027],{"type":46,"value":4540},{"type":40,"tag":4995,"props":5029,"children":5030},{},[5031],{"type":46,"value":5032},"Best-effort mutual exclusion, single Redis",{"type":40,"tag":4995,"props":5034,"children":5035},{},[5036],{"type":46,"value":5037},"Lost on Redis failure",{"type":40,"tag":4968,"props":5039,"children":5040},{},[5041,5046,5051],{"type":40,"tag":4995,"props":5042,"children":5043},{},[5044],{"type":46,"value":5045},"Redlock (N Redis instances)",{"type":40,"tag":4995,"props":5047,"children":5048},{},[5049],{"type":46,"value":5050},"Need lock to survive single-node failure",{"type":40,"tag":4995,"props":5052,"children":5053},{},[5054],{"type":46,"value":5055},"Complex, clock-dependent, controversial",{"type":40,"tag":4968,"props":5057,"children":5058},{},[5059,5064,5069],{"type":40,"tag":4995,"props":5060,"children":5061},{},[5062],{"type":46,"value":5063},"Idempotency key",{"type":40,"tag":4995,"props":5065,"children":5066},{},[5067],{"type":46,"value":5068},"Operations can be safely retried",{"type":40,"tag":4995,"props":5070,"children":5071},{},[5072],{"type":46,"value":5073},"Doesn't prevent concurrent execution, just duplicate effects",{"type":40,"tag":49,"props":5075,"children":5076},{},[5077],{"type":40,"tag":55,"props":5078,"children":5079},{},[5080],{"type":46,"value":5081},"Redlock caveats:",{"type":40,"tag":5083,"props":5084,"children":5085},"ul",{},[5086,5091,5103,5108],{"type":40,"tag":991,"props":5087,"children":5088},{},[5089],{"type":46,"value":5090},"Depends on synchronized clocks; clock skew can let two processes both believe they hold the lock.",{"type":40,"tag":991,"props":5092,"children":5093},{},[5094,5096,5101],{"type":46,"value":5095},"Kleppmann's \"How to do distributed locking\" argues it's unsafe for correctness-critical use. Add ",{"type":40,"tag":55,"props":5097,"children":5098},{},[5099],{"type":46,"value":5100},"fencing tokens",{"type":46,"value":5102}," (monotonically increasing values downstream services validate) as a safety layer.",{"type":40,"tag":991,"props":5104,"children":5105},{},[5106],{"type":46,"value":5107},"If the protected operation has side effects (API calls, charges), the lock alone isn't enough -- combine with idempotency keys.",{"type":40,"tag":991,"props":5109,"children":5110},{},[5111],{"type":46,"value":5112},"Reach for Redlock only when you have a specific reason single-instance Redis isn't enough; otherwise a DB constraint or single Redis lock is simpler.",{"type":40,"tag":61,"props":5114,"children":5116},{"id":5115},"the-priority-order",[5117],{"type":46,"value":5118},"The Priority Order",{"type":40,"tag":49,"props":5120,"children":5121},{},[5122],{"type":46,"value":5123},"When fixing a race, prefer solutions in this order -- higher numbers mean more code, complexity, and failure modes:",{"type":40,"tag":987,"props":5125,"children":5126},{},[5127,5137,5155,5172,5196,5206,5222],{"type":40,"tag":991,"props":5128,"children":5129},{},[5130,5135],{"type":40,"tag":55,"props":5131,"children":5132},{},[5133],{"type":46,"value":5134},"Unique constraint",{"type":46,"value":5136}," -- DB rejects duplicates, zero app code.",{"type":40,"tag":991,"props":5138,"children":5139},{},[5140,5145,5147,5153],{"type":40,"tag":55,"props":5141,"children":5142},{},[5143],{"type":46,"value":5144},"Atomic update",{"type":46,"value":5146}," -- ",{"type":40,"tag":93,"props":5148,"children":5150},{"className":5149},[],[5151],{"type":46,"value":5152},"SET x = x + 1 WHERE condition",{"type":46,"value":5154},", inherently atomic.",{"type":40,"tag":991,"props":5156,"children":5157},{},[5158,5163,5164,5170],{"type":40,"tag":55,"props":5159,"children":5160},{},[5161],{"type":46,"value":5162},"Upsert",{"type":46,"value":5146},{"type":40,"tag":93,"props":5165,"children":5167},{"className":5166},[],[5168],{"type":46,"value":5169},"INSERT ... ON CONFLICT UPDATE",{"type":46,"value":5171},", atomic create-or-update.",{"type":40,"tag":991,"props":5173,"children":5174},{},[5175,5180,5181,5187,5188,5194],{"type":40,"tag":55,"props":5176,"children":5177},{},[5178],{"type":46,"value":5179},"Redis atomic ops",{"type":46,"value":5146},{"type":40,"tag":93,"props":5182,"children":5184},{"className":5183},[],[5185],{"type":46,"value":5186},"DECR",{"type":46,"value":1043},{"type":40,"tag":93,"props":5189,"children":5191},{"className":5190},[],[5192],{"type":46,"value":5193},"SETNX",{"type":46,"value":5195},", Lua, for fast in-memory coordination.",{"type":40,"tag":991,"props":5197,"children":5198},{},[5199,5204],{"type":40,"tag":55,"props":5200,"children":5201},{},[5202],{"type":46,"value":5203},"Optimistic locking",{"type":46,"value":5205}," -- version column in WHERE, retries on conflict.",{"type":40,"tag":991,"props":5207,"children":5208},{},[5209,5214,5215,5220],{"type":40,"tag":55,"props":5210,"children":5211},{},[5212],{"type":46,"value":5213},"Pessimistic locking",{"type":46,"value":5146},{"type":40,"tag":93,"props":5216,"children":5218},{"className":5217},[],[5219],{"type":46,"value":3382},{"type":46,"value":5221},", blocks concurrent access.",{"type":40,"tag":991,"props":5223,"children":5224},{},[5225,5230],{"type":40,"tag":55,"props":5226,"children":5227},{},[5228],{"type":46,"value":5229},"Distributed lock (Redis\u002FRedlock)",{"type":46,"value":5231}," -- cross-process mutual exclusion, last resort.",{"type":40,"tag":61,"props":5233,"children":5235},{"id":5234},"anti-patterns",[5236],{"type":46,"value":5237},"Anti-Patterns",{"type":40,"tag":5083,"props":5239,"children":5240},{},[5241,5263,5281,5307],{"type":40,"tag":991,"props":5242,"children":5243},{},[5244,5249,5250,5255,5256,5261],{"type":40,"tag":55,"props":5245,"children":5246},{},[5247],{"type":46,"value":5248},"Check-then-act (TOCTOU)",{"type":46,"value":5146},{"type":40,"tag":93,"props":5251,"children":5253},{"className":5252},[],[5254],{"type":46,"value":159},{"type":46,"value":1011},{"type":40,"tag":93,"props":5257,"children":5259},{"className":5258},[],[5260],{"type":46,"value":263},{"type":46,"value":5262},", or \"check it doesn't exist, then insert.\" Two requests both pass the check and both write. Fix with a unique constraint.",{"type":40,"tag":991,"props":5264,"children":5265},{},[5266,5271,5273,5279],{"type":40,"tag":55,"props":5267,"children":5268},{},[5269],{"type":46,"value":5270},"Read-modify-write in app code",{"type":46,"value":5272}," -- read a counter or balance, compute the new value, write it back. Concurrent writers overwrite each other's increments. Fix with atomic ",{"type":40,"tag":93,"props":5274,"children":5276},{"className":5275},[],[5277],{"type":46,"value":5278},"UPDATE ... SET x = x + n",{"type":46,"value":5280}," or a version column.",{"type":40,"tag":991,"props":5282,"children":5283},{},[5284,5289,5291,5297,5299,5305],{"type":40,"tag":55,"props":5285,"children":5286},{},[5287],{"type":46,"value":5288},"Acting on a stale status",{"type":46,"value":5290}," -- read ",{"type":40,"tag":93,"props":5292,"children":5294},{"className":5293},[],[5295],{"type":46,"value":5296},"status === \"pending\"",{"type":46,"value":5298},", then charge\u002Fship\u002Fsend. A retry reads the same status and acts twice. Gate the side effect on a conditional transition (",{"type":40,"tag":93,"props":5300,"children":5302},{"className":5301},[],[5303],{"type":46,"value":5304},"UPDATE ... WHERE status = 'pending'",{"type":46,"value":5306},") and check rows affected.",{"type":40,"tag":991,"props":5308,"children":5309},{},[5310,5315],{"type":40,"tag":55,"props":5311,"children":5312},{},[5313],{"type":46,"value":5314},"Holding a distributed lock across an external call without a fence",{"type":46,"value":5316}," -- the lock can expire mid-operation while a second worker acquires it. Carry a fencing token so stale holders are rejected.",{"type":40,"tag":61,"props":5318,"children":5320},{"id":5319},"related-traps",[5321],{"type":46,"value":5322},"Related Traps",{"type":40,"tag":5083,"props":5324,"children":5325},{},[5326,5336,5346],{"type":40,"tag":991,"props":5327,"children":5328},{},[5329,5334],{"type":40,"tag":55,"props":5330,"children":5331},{},[5332],{"type":46,"value":5333},"Idempotency",{"type":46,"value":5335}," -- many races manifest as duplicate operations. If every operation is idempotent, races cause no harm. Idempotency keys are the primary defense against webhook and queue retry races.",{"type":40,"tag":991,"props":5337,"children":5338},{},[5339,5344],{"type":40,"tag":55,"props":5340,"children":5341},{},[5342],{"type":46,"value":5343},"Consistency Models",{"type":46,"value":5345}," -- replica lag creates races even in single-process code: you write to the primary, read from a replica, data isn't there yet. Read-after-write must hit the primary.",{"type":40,"tag":991,"props":5347,"children":5348},{},[5349,5354,5356,5362],{"type":40,"tag":55,"props":5350,"children":5351},{},[5352],{"type":46,"value":5353},"Object Store as Database",{"type":46,"value":5355}," -- S3 GET-modify-PUT without ",{"type":40,"tag":93,"props":5357,"children":5359},{"className":5358},[],[5360],{"type":46,"value":5361},"If-Match",{"type":46,"value":5363}," is a read-modify-write race. Use conditional writes for optimistic concurrency on object storage.",{"type":40,"tag":5365,"props":5366,"children":5367},"style",{},[5368],{"type":46,"value":5369},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":5371,"total":4367},[5372,5383,5396,5406,5416,5429,5441],{"slug":5373,"name":5373,"fn":5374,"description":5375,"org":5376,"tags":5377,"stars":23,"repoUrl":24,"updatedAt":5382},"staff-engineering-skills-backpressure","implement backpressure in streaming pipelines","Prevent unbounded resource growth when producers outpace consumers. Use when writing producer-consumer code, queue processing, batch operations, fan-out patterns, streaming pipelines, or any code where work is generated faster than it can be processed. Activates on patterns like Promise.all on dynamic-sized arrays, unbounded in-memory queues, producer loops without depth checks, fire-and-forget async calls in loops, or any buffer between a producer and consumer without a size limit.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5378,5379],{"name":14,"slug":15,"type":16},{"name":5380,"slug":5381,"type":16},"Performance","performance","2026-06-17T08:40:42.723559",{"slug":5384,"name":5384,"fn":5385,"description":5386,"org":5387,"tags":5388,"stars":23,"repoUrl":24,"updatedAt":5395},"staff-engineering-skills-cache-invalidation","implement cache invalidation strategies","Prevent stale data bugs caused by missing or incomplete cache invalidation. Use when adding caching layers (Redis, in-memory Map, CDN, HTTP cache headers), optimizing read performance, or reviewing code that caches query results, API responses, or computed values. Activates on patterns like cache.set without cache.delete on write paths, unbounded Map\u002Fobject caches, TTL-only invalidation on security-sensitive data, Cache-Control headers on mutable content, or any caching where the write path doesn't invalidate the read cache.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5389,5390,5393,5394],{"name":14,"slug":15,"type":16},{"name":5391,"slug":5392,"type":16},"Caching","caching",{"name":18,"slug":19,"type":16},{"name":5380,"slug":5381,"type":16},"2026-06-17T08:40:45.194583",{"slug":5397,"name":5397,"fn":5398,"description":5399,"org":5400,"tags":5401,"stars":23,"repoUrl":24,"updatedAt":5405},"staff-engineering-skills-cardinality","prevent cardinality traps in systems code","Detect and prevent cardinality traps in systems code. Use when writing code that iterates over collections, stores items in memory, creates per-entity resources, or fans out operations across a set of items. Activates on patterns like loops over query results, in-memory Maps\u002FSets populated from databases, or \"one X per Y\" resource allocation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5402,5403,5404],{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},{"name":5380,"slug":5381,"type":16},"2026-06-17T08:40:40.264608",{"slug":5407,"name":5407,"fn":5408,"description":5409,"org":5410,"tags":5411,"stars":23,"repoUrl":24,"updatedAt":5415},"staff-engineering-skills-clock-skew","prevent clock skew bugs in distributed systems","Prevent bugs caused by assuming clocks are synchronized or monotonic. Use when writing code that compares timestamps across machines, measures durations, sets lock expiry, orders distributed events, deduplicates by time window, or uses Date.now() for anything other than logging or display. Activates on patterns like Date.now() used for duration measurement, absolute timestamp expiry shared across machines, wall clock timestamps for event ordering, last-write-wins conflict resolution with timestamps, or timeout calculations using wall clock time.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5412,5413,5414],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},"2026-06-17T08:40:37.803541",{"slug":5417,"name":5417,"fn":5418,"description":5419,"org":5420,"tags":5421,"stars":23,"repoUrl":24,"updatedAt":5428},"staff-engineering-skills-consistency-models","manage consistency models in distributed systems","Prevent stale read bugs caused by replica lag, cache staleness, and index delay. Use when writing code that reads data after writing it, uses read replicas, caches query results, reads from search indexes, or builds event-driven read models. Activates on patterns like create-then-redirect, update-then-read, cache-aside with TTL, search-after-create, or any write followed by a read that might hit a different data source.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5422,5423,5426,5427],{"name":14,"slug":15,"type":16},{"name":5424,"slug":5425,"type":16},"Database","database",{"name":18,"slug":19,"type":16},{"name":5380,"slug":5381,"type":16},"2026-06-17T08:40:46.442182",{"slug":5430,"name":5430,"fn":5431,"description":5432,"org":5433,"tags":5434,"stars":23,"repoUrl":24,"updatedAt":5440},"staff-engineering-skills-denormalization","prevent data model denormalization traps","Detect and prevent denormalization traps when designing data models. Use when writing code that copies fields between tables, embeds related data in documents, caches composed objects, or adds redundant columns to avoid joins. Activates on patterns like storing derived\u002Fcopied data, syncing fields across tables, or embedding nested objects in document stores.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5435,5436,5439],{"name":14,"slug":15,"type":16},{"name":5437,"slug":5438,"type":16},"Data Modeling","data-modeling",{"name":5424,"slug":5425,"type":16},"2026-06-17T08:40:53.835868",{"slug":5442,"name":5442,"fn":5443,"description":5444,"org":5445,"tags":5446,"stars":23,"repoUrl":24,"updatedAt":5452},"staff-engineering-skills-distributed-system-fallacies","design resilient distributed systems","Prevent failures caused by treating network calls like function calls. Use when writing code that calls external services, splits a monolith into microservices, chains multiple API calls, orchestrates distributed workflows, or handles requests that depend on other services. Activates on patterns like sequential service calls without timeouts, fetch\u002Faxios calls without error handling, multi-service writes without compensation, hardcoded service URLs, or any code that assumes the network is reliable, fast, or free.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5447,5450,5451],{"name":5448,"slug":5449,"type":16},"API Development","api-development",{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},"2026-06-17T08:40:47.666795",{"items":5454,"total":5608},[5455,5474,5487,5497,5514,5529,5543,5560,5573,5585,5596,5601],{"slug":5456,"name":5456,"fn":5457,"description":5458,"org":5459,"tags":5460,"stars":5471,"repoUrl":5472,"updatedAt":5473},"trigger-authoring-chat-agent","author durable AI chat agents with Trigger.dev","Author and run a durable AI chat agent with chat.agent from @trigger.dev\u002Fsdk\u002Fai: the per-turn run loop, why you MUST spread ...chat.toStreamTextOptions() first, returning a StreamTextResult vs calling chat.pipe(), the two server actions (chat.createStartSessionAction + auth.createPublicToken), and wiring useChat to useTriggerChatTransport. Load this when building, modifying, or debugging a chat backend (the agent task or its lifecycle hooks) or its React transport, when declaring typed tools or custom data parts, or when migrating a plain AI SDK streamText route to chat.agent.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5461,5464,5467,5468],{"name":5462,"slug":5463,"type":16},"Agents","agents",{"name":5465,"slug":5466,"type":16},"SDK","sdk",{"name":9,"slug":8,"type":16},{"name":5469,"slug":5470,"type":16},"Workflow Automation","workflow-automation",14401,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Ftrigger.dev","2026-07-02T17:12:52.307135",{"slug":5475,"name":5475,"fn":5476,"description":5477,"org":5478,"tags":5479,"stars":5471,"repoUrl":5472,"updatedAt":5486},"trigger-authoring-tasks","author backend Trigger.dev tasks","Covers writing backend Trigger.dev tasks with @trigger.dev\u002Fsdk: defining task() and schemaTask(), the run function and its ctx, retries, waits, queues and concurrency, idempotency keys, run metadata, logging, triggering other tasks (and the Result shape), scheduled\u002Fcron tasks, and the essentials of trigger.config.ts. Load this whenever you are authoring or editing code inside a \u002Ftrigger directory, defining a task, or writing backend code that triggers tasks. Realtime\u002FReact hooks and AI chat are covered by separate skills.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5480,5483,5484,5485],{"name":5481,"slug":5482,"type":16},"Backend","backend",{"name":5465,"slug":5466,"type":16},{"name":9,"slug":8,"type":16},{"name":5469,"slug":5470,"type":16},"2026-07-02T17:12:48.396964",{"slug":5488,"name":5488,"fn":5489,"description":5490,"org":5491,"tags":5492,"stars":5471,"repoUrl":5472,"updatedAt":5496},"trigger-chat-agent-advanced","manage Trigger.dev chat sessions and transports","Advanced and operational chat.agent capabilities for Trigger.dev, loaded on demand. Load this when working on the raw Sessions primitive (sessions \u002F SessionHandle), a custom chat transport or the realtime wire protocol, durable sub-agents (AgentChat, chat.stream.writer), human-in-the-loop, steering, actions, background injection (chat.defer \u002F chat.inject), fast starts (preload, Head Start via @trigger.dev\u002Fsdk\u002Fchat-server), context resilience (compaction, recovery boot, OOM, large payloads), chat.local run-scoped state, offline testing with mockChatAgent, or prerelease\u002Fversion upgrades. For the everyday chat.agent({...}) definition and the useTriggerChatTransport happy path, use the trigger-authoring-chat-agent skill instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5493,5494,5495],{"name":5462,"slug":5463,"type":16},{"name":9,"slug":8,"type":16},{"name":5469,"slug":5470,"type":16},"2026-07-02T17:12:51.03018",{"slug":5498,"name":5498,"fn":5499,"description":5500,"org":5501,"tags":5502,"stars":5471,"repoUrl":5472,"updatedAt":5513},"trigger-realtime-and-frontend","subscribe to Trigger.dev runs in realtime","Trigger.dev client\u002Ffrontend surface: subscribe to runs in realtime (runs.subscribeToRun and the @trigger.dev\u002Freact-hooks hook useRealtimeRun), consume metadata and AI\u002Ftext streams in React (useRealtimeStream), trigger tasks from the browser (useTaskTrigger, useRealtimeTaskTrigger), and mint scoped frontend credentials with auth.createPublicToken \u002F auth.createTriggerPublicToken. Load when wiring a frontend (React\u002FNext.js\u002FRemix) or backend-for-frontend to show live run progress, status badges, token streams, trigger buttons, or wait-token approval UIs. NOT for writing the backend task itself (streams.define \u002F metadata.set is trigger-authoring-tasks territory); this is the consumer side.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5503,5506,5509,5512],{"name":5504,"slug":5505,"type":16},"Frontend","frontend",{"name":5507,"slug":5508,"type":16},"React","react",{"name":5510,"slug":5511,"type":16},"Real-time","real-time",{"name":9,"slug":8,"type":16},"2026-07-02T17:12:49.717706",{"slug":5515,"name":5515,"fn":5516,"description":5517,"org":5518,"tags":5519,"stars":5526,"repoUrl":5527,"updatedAt":5528},"trigger-agents","orchestrate AI agents with Trigger.dev","AI agent patterns with Trigger.dev - orchestration, parallelization, routing, evaluator-optimizer, and human-in-the-loop. Use when building LLM-powered tasks that need parallel workers, approval gates, tool calling, or multi-step agent workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5520,5521,5524,5525],{"name":5462,"slug":5463,"type":16},{"name":5522,"slug":5523,"type":16},"Multi-Agent","multi-agent",{"name":9,"slug":8,"type":16},{"name":5469,"slug":5470,"type":16},30,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fskills","2026-04-06T18:54:46.023553",{"slug":5530,"name":5530,"fn":5531,"description":5532,"org":5533,"tags":5534,"stars":5526,"repoUrl":5527,"updatedAt":5542},"trigger-config","configure Trigger.dev project settings","Configure Trigger.dev projects with trigger.config.ts. Use when setting up build extensions for Prisma, Playwright, FFmpeg, Python, or customizing deployment settings.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5535,5538,5541],{"name":5536,"slug":5537,"type":16},"Configuration","configuration",{"name":5539,"slug":5540,"type":16},"Deployment","deployment",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:44.764258",{"slug":5544,"name":5544,"fn":5545,"description":5546,"org":5547,"tags":5548,"stars":5526,"repoUrl":5527,"updatedAt":5559},"trigger-cost-savings","optimize Trigger.dev task costs","Analyze Trigger.dev tasks, schedules, and runs for cost optimization opportunities. Use when asked to reduce spend, optimize costs, audit usage, right-size machines, or review task efficiency. Requires Trigger.dev MCP tools for run analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5549,5552,5555,5558],{"name":5550,"slug":5551,"type":16},"Analytics","analytics",{"name":5553,"slug":5554,"type":16},"Cost Optimization","cost-optimization",{"name":5556,"slug":5557,"type":16},"Operations","operations",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:48.555552",{"slug":5561,"name":5561,"fn":5562,"description":5563,"org":5564,"tags":5565,"stars":5526,"repoUrl":5527,"updatedAt":5572},"trigger-realtime","monitor Trigger.dev tasks in real-time","Subscribe to Trigger.dev task runs in real-time from frontend and backend. Use when building progress indicators, live dashboards, streaming AI\u002FLLM responses, or React components that display task status.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5566,5567,5570,5571],{"name":5504,"slug":5505,"type":16},{"name":5568,"slug":5569,"type":16},"Observability","observability",{"name":5510,"slug":5511,"type":16},{"name":9,"slug":8,"type":16},"2026-04-06T18:54:47.293822",{"slug":5574,"name":5574,"fn":5575,"description":5576,"org":5577,"tags":5578,"stars":5526,"repoUrl":5527,"updatedAt":5584},"trigger-setup","set up Trigger.dev in projects","Set up Trigger.dev in your project. Use when adding Trigger.dev for the first time, creating trigger.config.ts, or initializing the trigger directory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5579,5580,5583],{"name":5536,"slug":5537,"type":16},{"name":5581,"slug":5582,"type":16},"Local Development","local-development",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:42.280816",{"slug":5586,"name":5586,"fn":5587,"description":5588,"org":5589,"tags":5590,"stars":5526,"repoUrl":5527,"updatedAt":5595},"trigger-tasks","build durable background tasks with Trigger.dev","Build AI agents, workflows and durable background tasks with Trigger.dev. Use when creating tasks, triggering jobs, handling retries, scheduling cron jobs, or implementing queues and concurrency control.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5591,5592,5593,5594],{"name":5462,"slug":5463,"type":16},{"name":5481,"slug":5482,"type":16},{"name":9,"slug":8,"type":16},{"name":5469,"slug":5470,"type":16},"2026-04-06T18:54:43.514369",{"slug":5373,"name":5373,"fn":5374,"description":5375,"org":5597,"tags":5598,"stars":23,"repoUrl":24,"updatedAt":5382},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5599,5600],{"name":14,"slug":15,"type":16},{"name":5380,"slug":5381,"type":16},{"slug":5384,"name":5384,"fn":5385,"description":5386,"org":5602,"tags":5603,"stars":23,"repoUrl":24,"updatedAt":5395},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[5604,5605,5606,5607],{"name":14,"slug":15,"type":16},{"name":5391,"slug":5392,"type":16},{"name":18,"slug":19,"type":16},{"name":5380,"slug":5381,"type":16},26]