{
  "id": "database/sqlite-cannot-rollback-no-savepoint",
  "signature": "sqlite3.OperationalError: cannot rollback - no transaction is active",
  "signature_zh": "sqlite3.OperationalError: 无法回滚 - 没有活动的事务",
  "regex": "cannot rollback - no transaction is active",
  "domain": "database",
  "category": "runtime_error",
  "subcategory": null,
  "root_cause": "A ROLLBACK command was issued without a corresponding BEGIN TRANSACTION, or a savepoint name was used that does not exist.",
  "root_cause_type": "generic",
  "root_cause_zh": "发出了 ROLLBACK 命令，但没有对应的 BEGIN TRANSACTION，或者使用了不存在的保存点名称。",
  "versions": [
    {
      "version": "SQLite 3.42.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "SQLite 3.43.2",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "SQLite 3.44.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "",
      "why_fails": "If the code already has a transaction, this creates nested transactions that may not be handled correctly, leading to 'cannot commit - no transaction is active' errors later.",
      "fail_rate": 0.6,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "The WAL mode affects concurrency and crash recovery, not transaction management. It does not fix missing transactions.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Wrap the ROLLBACK in a try-except block and only execute it if a transaction is active. In Python: `try: cursor.execute('ROLLBACK') except sqlite3.OperationalError: pass`. Alternatively, use a context manager: `with connection: cursor.execute(...)` which auto-commits/rolls back.",
      "success_rate": 0.95,
      "how": "Wrap the ROLLBACK in a try-except block and only execute it if a transaction is active. In Python: `try: cursor.execute('ROLLBACK') except sqlite3.OperationalError: pass`. Alternatively, use a context manager: `with connection: cursor.execute(...)` which auto-commits/rolls back.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Review the code to ensure every ROLLBACK is paired with a BEGIN TRANSACTION. Use a connection wrapper that tracks transaction state (e.g., a flag `in_transaction` set to True on BEGIN and False on COMMIT/ROLLBACK).",
      "success_rate": 0.9,
      "how": "Review the code to ensure every ROLLBACK is paired with a BEGIN TRANSACTION. Use a connection wrapper that tracks transaction state (e.g., a flag `in_transaction` set to True on BEGIN and False on COMMIT/ROLLBACK).",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Wrap the ROLLBACK in a try-except block and only execute it if a transaction is active. In Python: `try: cursor.execute('ROLLBACK') except sqlite3.OperationalError: pass`. Alternatively, use a context manager: `with connection: cursor.execute(...)` which auto-commits/rolls back.",
    "Review the code to ensure every ROLLBACK is paired with a BEGIN TRANSACTION. Use a connection wrapper that tracks transaction state (e.g., a flag `in_transaction` set to True on BEGIN and False on COMMIT/ROLLBACK)."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://www.sqlite.org/lang_transaction.html",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.87,
  "fix_success_rate": 0.95,
  "resolvable": "true",
  "first_seen": "2023-05-12",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}