{"record":{"id":"b2932b87cb634ba5","repo":"linshenkx/prompt-optimizer","slug":"database-transaction-error-for-key-key-error","errorCode":null,"errorMessage":"Database transaction error for key ${key}: ${error.message}. Please try again.","messagePattern":"Database transaction error for key (.+?): (.+?)\\. Please try again\\.","errorType":"exception","errorClass":"StorageError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/storage/dexieStorageProvider.ts","lineNumber":308,"sourceCode":"\n          // 写入新值\n          await tx.table('storage').put({\n            key,\n            value: JSON.stringify(newValue),\n            timestamp: Date.now()\n          });\n        } catch (innerError) {\n          // 事务内部错误，让事务回滚\n          console.error(`Transaction operation failed (${key}):`, innerError);\n          throw innerError;\n        }\n      });\n    } catch (error) {\n      console.error(`Atomic update failed (${key}):`, error);\n\n      // 如果是Dexie事务错误，提供更详细的错误信息\n      if (this.isError(error) && error.name === 'PrematureCommitError') {\n        throw new StorageError(\n          `Database transaction error for key ${key}: ${error.message}. Please try again.`,\n          'write',\n        );\n      }\n\n      throw new StorageError(`Failed to perform atomic update: ${key}`, 'write');\n    }\n  }\n\n  /**\n   * 批量更新操作\n   */\n  async batchUpdate(operations: Array<{\n    key: string;\n    operation: 'set' | 'remove';\n    value?: string;\n  }>): Promise<void> {\n    await this.initialize();","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/storage/dexieStorageProvider.ts#L290-L326","documentation":"Specialized StorageError from _performAtomicUpdate when Dexie raises a PrematureCommitError — Dexie's error for code that 'commits' a transaction by doing non-transactional or async-incompatible operations inside it. The message embeds the key and the original error and asks the user to retry.","triggerScenarios":"The update function passed to update() performs operations Dexie cannot include in the transaction: awaiting non-Dexie promises, calling other async APIs, or opening new transactions inside the callback, triggering PrematureCommitError inside db.transaction().","commonSituations":"Calling external APIs, timers, or other storage backends inside the atomic update callback; upgrading Dexie versions where transaction semantics tightened; doing IDB events (onsuccess handlers) manually inside the transaction.","solutions":["Make the update callback synchronous with respect to non-Dexie async work: compute values outside, only do Dexie ops inside","Pre-fetch anything async before calling update() and pass results in via closure","Retry the operation once on this specific message, since PrematureCommitError is often transient under contention"],"exampleFix":"// before\nawait provider.update('k', async (old) => {\n  const extra = await fetch('/api/x').then(r => r.json()); // kills the transaction\n  return merge(old, extra);\n});\n\n// after\nconst extra = await fetch('/api/x').then(r => r.json());\nawait provider.update('k', (old) => merge(old, extra));","handlingStrategy":"retry","validationCode":"// Do all non-Dexie async work BEFORE the atomic update\nconst external = await loadExternalData();\nawait provider.update(key, (old) => merge(old, external)); // callback stays Dexie-only/sync","typeGuard":"const isPrematureCommit = (e: unknown): e is StorageError =>\n  e instanceof StorageError && /PrematureCommit|transaction error/i.test(String((e as Error).message));","tryCatchPattern":"try { await provider.update(key, fn); } catch (e) { if (isPrematureCommit(e)) { await sleep(100); return provider.update(key, fn); } throw e; }","preventionTips":["Never await non-Dexie promises inside the update() callback","Read/write only via the same Dexie instance inside transactions","Refactor update callbacks to pure synchronous transforms over pre-fetched data"],"tags":["storage","dexie","transactions","premature-commit"],"backgroundTag":"dexie-premature-commit","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}