未提交的事务在客户端异常断开时会自动回滚,前提是使用标准事务流程(如begin)且未显式提交或回滚;若autocommit=1,则单条语句立即生效不可回滚。

事务没提交就断开,数据到底回滚了吗
MySQL、PostgreSQL 等主流数据库在客户端异常断开时,**未提交的事务会自动回滚**,这是由连接层协议和事务隔离机制共同保证的。但前提是:你用的是标准事务流程(BEGIN / START TRANSACTION),且没有显式执行 COMMIT 或 ROLLBACK。
常见错误现象:INSERT INTO users VALUES (123, 'test'); 执行后直接关掉终端,以为“没保存”,结果发现数据还在——那说明你根本没开启事务,语句以自动提交(autocommit=1)模式单独执行了。
- 检查当前 autocommit 状态:
SELECT @@autocommit;(MySQL)或SHOW AUTOCOMMIT;(psql 中用\set SHOW_AUTOCOMMIT on) - 想确保可回滚,务必先写
BEGIN;哪怕只改一行,也要包在事务里 - 某些 ORM(如 Django 默认)会隐式开启事务,但 raw SQL 不会,别依赖框架行为
已 COMMIT 的误操作怎么恢复
一旦 COMMIT 成功,数据库不会保留旧值快照,常规 SQL 无法“撤销”。恢复唯一可行路径是依赖外部机制:备份、binlog(MySQL)、WAL(PostgreSQL)或时间点恢复(PITR)。
使用场景:线上误删整张表、UPDATE 漏写 WHERE 条件、批量 UPDATE 写错字段值。
- MySQL 必须开启
binlog_format = ROW,否则 binlog 只记语句,无法精确还原行级变更 - 从 binlog 回放时,用
mysqlbinlog --stop-datetime="2024-04-05 10:23:00"截断到出错前一刻,再重放 - PostgreSQL 需提前配置
archive_mode = on并启用 WAL 归档,否则 pg_wal 目录滚动覆盖后不可逆 - 不要指望
FLASHBACK TABLE(Oracle 特有),MySQL 8.0+ 的FLASHBACK仅限企业版且限制极多
SET autocommit = 0 后忘了 COMMIT,连接断了会怎样
这和第一个问题不同:你手动关了自动提交,又没显式 COMMIT 或 ROLLBACK,然后连接中断(比如网络闪断、应用 crash)。此时事务状态由服务端决定——绝大多数情况下,连接关闭即触发隐式 ROLLBACK。
hdhcms网站支持PC、手机版,同时后台支持公众号的接入,包括微信服务号订阅号,可以设置自动回复及服务号菜单及认证订阅号菜单。 1、网站上线方法: 1.1本网站运行环境为:IIS6.5+SQLITE 1.2将网站解压到网站目录 1.3数据库默认为SQLITE,包括在解压目录内,无须修改 1.4 完成上面的配置后通过所绑定的域名即可运行2网址访问及后台访问配置
但注意例外:MySQL 5.7+ 在 wait_timeout 超时前若连接仍空闲,事务会挂起;超时后才回滚。而 PostgreSQL 更严格,连接终止瞬间就清理所有未完成事务。
- 永远不要靠“等超时”来清理事务,用
SHOW PROCESSLIST;(MySQL)或SELECT * FROM pg_stat_activity WHERE state = 'idle in transaction';主动查漏 - 应用层必须配超时控制:如 JDBC 的
socketTimeout和queryTimeout,避免长事务卡住连接池 -
autocommit = 0是会话级设置,新连接默认仍是 1,别以为设过一次就全局生效
用 DELETE + INSERT 模拟 UPDATE 为什么更难回滚
有些同学为规避锁或实现“全量替换”,用 DELETE FROM t WHERE id = 123; 接着 INSERT INTO t VALUES (...);。这种写法看似简单,实则放大了恢复难度。
原因在于:DELETE 产生的 binlog/WAL 记录是“删除动作”,INSERT 是“新增动作”,两者无逻辑关联。如果只回放 binlog 到 DELETE 前,INSERT 不会自动消失;反之亦然。
- 对比原生
UPDATE:binlog 记录的是“旧值→新值”的完整映射,部分工具(如 pt-online-schema-change)能据此反向生成回滚语句 - DELETE+INSERT 还可能破坏外键约束、触发器顺序、自增 ID 连续性,导致恢复后业务逻辑异常
- 若真要模拟更新,优先用
REPLACE INTO(MySQL)或INSERT ... ON CONFLICT DO UPDATE(PostgreSQL),它们是原子操作,日志可追溯
真正棘手的不是语法怎么写,而是你得清楚每条语句落在哪一层日志里、被哪个备份策略覆盖、有没有人动过归档配置。这些细节不核对清楚,恢复时大概率要重跑迁移脚本。









