第七章:数据持久存储与交换-sqlite3嵌入式关系数据库事务回滚:丢弃变更的 commit/rollback 实战
1. 为什么本地数据交换场景离不开 sqlite3 事务回滚如果你在做本地数据持久存储与交换比如把采集到的日志、配置项、任务清单写进一个单文件数据库再导出给别的程序用sqlite3 几乎是绕不开的选择。它是嵌入式关系数据库不需要单独起服务一个.db文件就是全部Python 标准库直接import sqlite3就能用。但很多人第一次写多步写入时会踩同一个坑删了一半、插了一半程序报错退出数据库却停在“半成品”状态下次读出来数据对不上。这就是事务要解决的问题。sqlite3 默认把每条语句当成一个隐式事务但当你需要“一组操作要么全成、要么全不成”时必须自己控制commit()和rollback()。commit()把变更落盘rollback()把从上次提交之后的所有未提交变更全部丢弃数据库回到事务开始前的样子。理解 rollback 的机制和边界是本地数据交换可靠性的底线。这篇面向的是会用 Python 读写 sqlite3、但没系统搞清事务边界的开发者以及需要在本地做数据清洗、批量导入导出、失败可回退的人。核心检索词就是 sqlite3 事务回滚、rollback 丢弃变更、commit 与 rollback 对照。我会给可复制的配置片段、对照验证动作以及一套统一的凭据管理思路让你能独立复现“变更被正确丢弃”这件事。先说结论rollback 不是“撤销某一条语句”而是“丢弃当前事务内所有未提交的变更”。这个边界搞错排障时会怀疑人生。下面从场景、前置、配置、验证、排错一路走完。2. 前置准备Python sqlite3 环境与统一凭据通道 TaoToken在写事务代码之前先把环境和“调用凭据”这件事理清楚。环境部分很简单Python 3.8 以上自带 sqlite3不需要 pip 装任何东西。你可以用下面命令确认版本和 sqlite 库版本python3 -c import sqlite3; print(sqlite3.sqlite_version)输出类似3.45.1就说明可用。注意 Python 的 sqlite3 模块版本和底层 SQLite 库版本是两回事事务行为以底层库为准一般 3.7 以上都支持我们要用的特性。那为什么这里要提 TaoToken因为很多本地数据交换脚本并不是纯离线的它可能要调用模型做字段清洗、做文本摘要、做结构化抽取然后再写回 sqlite。这时候你会散落一堆 API Key 在脚本里换环境就到处改。TaoToken 提供统一的 Key/API 通道把模型调用凭据集中管理脚本里只读一个环境变量即可。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 这个不加 UTM。我试过把清洗脚本里的模型调用统一走一个 base_url本地 sqlite 写入逻辑完全不变只把“取 Key”这一步抽出来。这样事务代码和凭据管理解耦回滚测试也不会因为 Key 失效而中断。你需要准备的东西一个可写的目录用来放todo.db测试库Python 3.8如果脚本要调模型去控制台建一个 Key模型对话页可以先验证通道是否通。控制台和 Key 管理在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 建 Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。这些链接的作用是让你在需要模型能力时有个统一出口而不是把 Key 硬编码进事务脚本。注意事务回滚本身是纯本地行为和任何网络调用无关。把凭据管理独立出来是为了让“回滚验证”这一步不被外部依赖干扰。你完全可以先不接模型纯本地跑通 rollback再叠加模型清洗。环境就绪后我们进入真正的事务配置。记住一个原则sqlite3 的with conn:上下文管理器在正常退出时自动 commit异常退出时自动 rollback。但很多人误以为它“总是回滚”其实它只在异常时回滚。手动调用conn.rollback()和conn.commit()才是显式控制。3. 可复制配置sqlite3 事务 commit/rollback 对照片段这一节给可直接运行的代码。先建一个测试库并插入初始数据然后做“删除 模拟报错 回滚”的对照实验。核心文件叫todo.db表叫project字段name和description。先跑建库脚本import sqlite3 db_filename todo.db with sqlite3.connect(db_filename) as conn: conn.execute( create table if not exists project ( name text primary key, description text ) ) conn.execute(insert or replace into project values (virtualenvwrapper, 管理虚拟环境)) conn.execute(insert or replace into project values (sqlite3, 嵌入式关系数据库)) conn.execute(insert or replace into project values (taotoken, 统一模型调用凭据)) conn.commit() print(init done)运行后todo.db里有三条记录。接下来是关键的对照脚本它把 commit 和 rollback 放在同一个 try/except 的不同分支import sqlite3 db_filename todo.db def show_projects(conn): cursor conn.cursor() cursor.execute(select name, description from project order by name) for name, desc in cursor.fetchall(): print( , name, |, desc) with sqlite3.connect(db_filename) as conn: print(Before changes:) show_projects(conn) try: cursor conn.cursor() cursor.execute(delete from project where name virtualenvwrapper) print(\nAfter delete (uncommitted):) show_projects(conn) raise RuntimeError(simulated error) except Exception as err: print(ERROR:, err) conn.rollback() else: conn.commit() print(\nAfter rollback:) show_projects(conn)这段代码的路径是删除virtualenvwrapper→ 打印未提交状态此时该行已“看不见”→ 抛异常 → 进入 except →conn.rollback()→ 再打印。预期结果是virtualenvwrapper重新出现因为变更被丢弃。如果你把raise RuntimeError注释掉就会走 else 分支执行conn.commit()此时virtualenvwrapper真正消失。这就是 commit 与 rollback 的对照。关于连接配置有几个参数值得写进你的模板conn sqlite3.connect( db_filename, timeout5.0, # 锁等待秒数 isolation_levelDEFERRED # 默认事务在首次写时开启 )isolation_level有三个值DEFERRED默认首次写操作才真正开事务、IMMEDIATE连接即尝试加写锁、EXCLUSIVE独占锁。本地单进程交换场景用默认即可如果你有多个进程同时写同一个 db建议用IMMEDIATE减少“database is locked”的概率。还有一个容易忽略的点with sqlite3.connect(...) as conn:这个上下文管理器管理的是事务不是连接。它不会在退出时关闭连接。连接关闭要显式conn.close()或者用contextlib.closing。很多人以为 with 块结束连接就关了结果文件句柄一直占着。提示如果你在 with 块里既手动conn.commit()又让 with 正常退出不会报错但语义上重复。建议要么全手动要么全交给 with别混着来否则回滚时机容易判断错。配置片段给完了下一节我们实际跑一遍看输出是否符合预期并确认“变更被正确丢弃”。4. 验证请求与成功结果确认 rollback 真的丢弃了变更把上一节的对照脚本保存为tx_demo.py运行python3 tx_demo.py预期输出Before changes: sqlite3 | 嵌入式关系数据库 taotoken | 统一模型调用凭据 virtualenvwrapper | 管理虚拟环境 After delete (uncommitted): sqlite3 | 嵌入式关系数据库 taotoken | 统一模型调用凭据 ERROR: simulated error After rollback: sqlite3 | 嵌入式关系数据库 taotoken | 统一模型调用凭据 virtualenvwrapper | 管理虚拟环境关键看两处After delete阶段virtualenvwrapper已经不在列表里说明删除在事务内生效After rollback阶段它又回来了说明 rollback 把未提交变更丢弃了。这就是“变更被正确丢弃”的直接证据。再做一个反向验证把raise RuntimeError注释掉重跑。输出会变成After rollback阶段virtualenvwrapper消失因为走了conn.commit()。两次运行对比你就能确认 commit 和 rollback 的分叉点。如果你想更严谨可以在 rollback 后用一条独立查询确认磁盘状态import sqlite3 conn sqlite3.connect(todo.db) print(conn.execute(select count(*) from project where namevirtualenvwrapper).fetchone()) conn.close()回滚后这条查询应返回(1,)说明数据还在。如果返回(0,)说明你的 rollback 没生效或者中间有别的连接提交了。这里有个边界要讲清楚rollback 只能丢弃当前连接当前事务内未提交的变更。如果另一个连接在你事务期间提交了对同一行的修改你的 rollback 不会影响它。sqlite 的锁机制会尽量阻止这种交叉写但读多写少的本地交换场景仍要注意。另外DDL 语句create/drop table在 sqlite 里是可以回滚的这点和某些数据库不同实测create table后 rollback表会消失。验证通过后如果你要把模型清洗结果写回建议流程是先本地事务写入原始数据 → 调模型拿结果 → 在同一个事务里更新 → 成功 commit失败 rollback。模型调用走 TaoToken 的模型对话入口 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 先验证通道再进脚本。这样即使模型超时本地数据也不会脏。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth事务本身报错不多但一旦叠加模型调用报错就会混在一起。下面按真实遇到的顺序列。401 Unauthorized如果你在事务脚本里调模型Key 没配或配错会返回 401。排查顺序先确认环境变量是否读到再确认 Key 是否有效。用 TaoToken 的话去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 重新生成一个写进环境变量export TAOTOKEN_API_KEY你的key脚本里读os.environ.get(TAOTOKEN_API_KEY)。注意别把 Key 写进todo.db或提交到仓库。local proxy failed这个报错通常出现在你配置了本地代理但代理没起来或者 base_url 指向了不可达地址。检查你的 base_url 是否写成https://taotoken.net/api以及本机网络是否正常。如果你在容器里跑确认容器能出网。这个错和事务无关但会中断你的“写入调用”流程导致事务走到 except 触发 rollback——从数据安全角度反而是好事。reading choices 相关报错典型是KeyError: choices或解析响应时reading choices失败。原因一般是响应体不是预期的 JSON 结构比如返回了错误页 HTML或者你用了流式但按非流式解析。排查先打印原始response.text确认结构再检查请求参数里的model是否写对。模型 ID 要和通道支持的保持一致。OAuth 相关报错如果你用某些 CLI 工具比如 Claude Code 类接入可能遇到 OAuth 流程失败。这类工具通常需要三件套Base URL、Key、Model ID。以 Claude Code 为例配置里要写全{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: 你的key, ANTHROPIC_MODEL: 你的模型ID } }三件套缺一不可。只填 Key 不填 Base URL会走默认端点导致 401 或连接失败只填 Base URL 不填 Model ID会报模型不存在。Cline 的 MCP 配置、Codex 的auth.json同理都要把 Base URL、Key、Model ID 写全。Codex 的auth.json大致结构{ base_url: https://taotoken.net/api, api_key: 你的key, model: 你的模型ID }database is locked这是 sqlite 特有的。多进程同时写或上一个连接没关。排查确认每个连接用完close()把timeout调大写操作前用BEGIN IMMEDIATE。如果你在事务里做了耗时的模型调用锁会一直持有建议把模型调用移到事务外拿到结果再开事务写入。rollback 后数据还在/没了先确认你是不是在 with 块里又手动 commit 了再确认是不是另一个连接提交了。用独立连接查询磁盘状态是最可靠的判断方式。排错时把“本地事务”和“网络调用”分开看能省一半时间。事务问题看锁和提交点网络问题看 Key、Base URL、Model ID 三件套。6. 长期编码与 Agent 场景用 Coding Plan 统一管理调用凭据如果你只是偶尔跑一次本地数据交换上面手动配 Key 就够了。但如果你在写长期运行的采集/清洗 Agent或者用 Claude Code、Cline 这类工具做持续编码凭据散落会变成维护负担。这时候可以考虑 Coding Plan把调用额度、Key、模型选择集中管理脚本和工具都从统一通道取。入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。它的价值在于你的事务脚本、CLI 工具、Agent 都指向同一个 Base URL 和 Key换模型或换额度只改一处。对于“本地 sqlite 写入 模型清洗”这种组合Agent 可以长时间跑失败自动 rollback成功 commit凭据不暴露在代码里。具体做法把 Base URL 固定为https://taotoken.net/apiKey 从环境变量读Model ID 按任务选。Claude Code 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有 Base URL、Key、Model ID 的完整填写示例。Cline 的 MCP 配置也是同样三件套写进对应的 settings 文件即可。回到事务本身长期运行时要加两个保护一是每次写入用独立事务别把整个 Agent 生命周期包在一个大事务里否则锁持有太久二是 rollback 后记录日志方便回溯哪批数据被丢弃。你可以把失败批次写进一个failed_batch表但注意这个写入本身也要在 rollback 之后的新事务里做否则会被一起回滚掉。最后给一个实用技巧在本地交换场景把“读”和“写”分开连接。读用只读连接写用单独连接减少锁冲突。写连接的事务模板就是本文第 3 节那段try 里做变更except 里 rollbackelse 里 commit。跑通一次后面所有本地数据交换都能复用。

相关新闻

AutoPentestX新手入门:第一条命令跑通从网络侦察到PDF报告的完整渗透测试流程

AutoPentestX新手入门:第一条命令跑通从网络侦察到PDF报告的完整渗透测试流程

【免费下载链接】AutoPentestX AutoPentestX – Automated Pentesting & Vulnerability Reporting Tool 项目地址: https://gitcode.com/gh_mirrors/au/AutoPentestX 点击查看 免费下载 AutoPentestX 是一款开源的自动化渗透测试与漏洞报告工具(Aut…

2026/10/11 11:14:31 阅读更多 →
杀戮尖塔Mod开发入门:从加载失败到可调试工程

杀戮尖塔Mod开发入门:从加载失败到可调试工程

简介:本资源是一份面向Java初学者与游戏模组开发新手的《杀戮尖塔》MOD制作系统入门教程,聚焦零基础环境搭建与核心开发流程。内容覆盖ModTheSpire、StsLib、BaseMod三大依赖库的订阅与配置原理,IntelliJ IDEA集成开发环境搭建,Ma…

2026/10/11 11:14:20 阅读更多 →
换脸进入实时时代:1080P 12fps 直播级工作流刚在 CSDN 刷屏,BFS 生态开始“卷速度“

换脸进入实时时代:1080P 12fps 直播级工作流刚在 CSDN 刷屏,BFS 生态开始“卷速度“

换脸进入实时时代:1080P 12fps 直播级工作流刚在 CSDN 刷屏,BFS 生态开始"卷速度" 【免费下载链接】BFS-Best-Face-Swap 项目地址: https://ai.gitcode.com/hf_mirrors/Alissonerdx/BFS-Best-Face-Swap 从"上传两张图&#xff0c…

2026/10/11 11:14:14 阅读更多 →

最新新闻

PostgreSQL性能压测实战:用TPC-H标准流程构建可复现基准测试环境

PostgreSQL性能压测实战:用TPC-H标准流程构建可复现基准测试环境

1. 项目概述:为什么TPC-H是检验PostgreSQL真实能力的“压力测试仪”你刚装好PostgreSQL,跑通了第一个CREATE TABLE,连上pgAdmin点了几次查询,心里有点小得意——数据库这玩意儿,好像也没那么难?别急&#x…

2026/10/12 5:09:00 阅读更多 →
基于Spring Boot的车牌识别停车场管理系统设计与实现

基于Spring Boot的车牌识别停车场管理系统设计与实现

1. 项目概述与选题价值1.1 这个系统到底解决什么问题我第一次看到这个题目的时候,第一反应是:这又是一个“典型的毕业设计式管理系统”?因为现在网上关于停车场、图书馆、宿舍管理这类CRUD项目太多了,很多同学开题时随手挑一个&am…

2026/10/12 5:09:00 阅读更多 →
Spring Boot农事管理系统毕业设计:从数据库建模到核心功能实现

Spring Boot农事管理系统毕业设计:从数据库建模到核心功能实现

写这个题目前,我先说句实在话:Spring Boot 农事管理系统,这个搭配在国内农业信息化方向的毕业设计里,已经算得上“经典款”了。经典意味着什么?意味着参考资料好找、技术路线成熟、踩坑记录也很多,不至于让…

2026/10/12 5:09:00 阅读更多 →
MATLAB快速谱相干:从一维时间序列到旋转机械多通道分析

MATLAB快速谱相干:从一维时间序列到旋转机械多通道分析

前几天我在一个设备诊断交流群里看到有人贴图:同一条轴上的两路振动信号,普通幅值谱看着都差不多,在某个轴承故障特征频率附近却同时出现了一处明显的相干峰。下面跟了几条回复,有人问“相干峰到底代表什么”,有人说“…

2026/10/12 5:09:00 阅读更多 →
SpringBoot+Vue+MySQL旅游网站毕设项目全解析:从数据库设计到部署答辩

SpringBoot+Vue+MySQL旅游网站毕设项目全解析:从数据库设计到部署答辩

每年毕业季我都会收到大量和“旅游网站”相关的咨询,这套 SpringBootVueMySQL 的某北方城市特色旅游网站平台,属于完成度很高的一类毕设项目。它带了完整数据库脚本、论文文档和部署说明,代码结构比多数网上流传的“半成品”要规矩得多。这篇…

2026/10/12 5:09:00 阅读更多 →
微客AI助手答疑:AI客服的会话记录存在哪?留存位置与合规要点

微客AI助手答疑:AI客服的会话记录存在哪?留存位置与合规要点

给商家配微客AI助手的时候,被问过的最认真的一组问题来自一位做母婴用品的店主。她问的不是价格也不是功能,而是:客户的聊天记录存在哪?谁能看到?会不会被拿去做别的?说实话,这三个问题比大多数…

2026/10/12 5:08:00 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →