事务未提交或autocommit关闭最常见:MySQL默认开启但客户端常关闭,PostgreSQL/Oracle默认不自动提交;需查@@autocommit或transaction_isolation,新开连接验证可见性,并检查权限、触发器及Doris等系统的publish延迟。

INSERT 返回影响行数 1,但 SELECT 查不到数据——八成不是 SQL 写错了,而是事务、可见性或权限卡在某个环节。
事务没提交或 autocommit 关闭了
这是最常见也最容易被忽略的点。MySQL 默认开启 autocommit,但很多客户端(DBeaver、Navicat)、连接池(HikariCP、Druid)或 ORM(SQLAlchemy、MyBatis)会默认关掉它。PostgreSQL 和 Oracle 则默认不自动提交。
- 执行
SELECT @@autocommit;(MySQL)或SHOW transaction_isolation;(PostgreSQL)确认当前会话状态 - 新开一个连接执行
SELECT,能查到说明原会话还在事务中;查不到就是没提交 - 临时验证:INSERT 后立刻在同一会话跑 SELECT,查得到 → 问题出在提交或连接隔离上
- 生产环境建议在连接字符串里显式加
autocommit=true,或代码中调用conn.autocommit = True
Doris / StarRocks 的事务可见性延迟
Doris 的 INSERT(包括 CTAS)走两阶段事务:先 commit,再异步 publish。如果 publish 超时(默认 10 秒),FE 会以 COMMITTED 状态返回,但数据尚未对后续查询可见。
- 审计日志里看到 INSERT 完成时间,但 FE 日志显示
commit和publish之间有 gap → 典型可见性延迟 - CTAS 语句本质是先建表、再走
handleInsertStmt(),复用普通 INSERT 流程,同样受 publish 控制 - 避免紧接查询:INSERT 后不要立刻
SELECT该表;可加SLEEP(1)或轮询SHOW LOAD WHERE LABEL = 'xxx'确认状态为FINISHED - 调大
streaming_load_rpc_max_alive_time_ms或transaction_publish_timeout_ms可缓解,但治标不治本
表名/库名写错 or 权限静默失败
插入和查询压根不是同一张表,或者用户没权限写入,却没报错——这类问题不会抛异常,只在日志里留痕。
- INSERT 的表名是
a,SELECT 却查t_user→ 检查 SQL 拼写、别名污染、USE database 是否切换正确 - 执行
SHOW GRANTS FOR CURRENT_USER;(MySQL)或\z table_name(psql)确认有INSERT和SELECT权限 - MySQL 8.0+ 在 strict mode 下权限不足可能跳过写入而不报错;PostgreSQL 通常直接报
permission denied for table xxx - Oracle 中没
COMMIT或SET AUTOCOMMIT ON,改完就断开 → 数据回滚,但客户端只看到 “PL/SQL procedure successfully completed”
触发器或约束导致隐式回滚
触发器里报错、CHECK 失败、外键不匹配……这些都可能让 INSERT 表面成功,实则被回滚,且错误被吞掉。
- MySQL 执行完 INSERT 后立刻跑
SHOW WARNINGS;,看有没有Warning | 1265 | Data truncated for column类提示 - PostgreSQL 触发器里漏写
RETURN NEW或误用RETURN NULL(BEFORE 触发器中会取消整条操作) - SQL Server 触发器里用
RAISERROR但没配SET XACT_ABORT ON→ 错误不传播,事务继续提交 - 所有数据库里,触发器中跨表 UPDATE 若
WHERE条件不匹配,ROW_COUNT()是 0,但不会报错
真正难排查的,往往不是语法错误,而是那些“没报错却没效果”的中间态:事务卡在 commit 和 publish 之间、权限缺半截、触发器逻辑分支没走到、autocommit 被连接池悄悄关掉。盯住日志里那几秒时间差,比反复检查 SQL 更有效。

















