接上一篇MySQL隐式提交再来看看老伙伴PG的隐式提交

PostgreSQL 的实际行为

PostgreSQL 支持在事务中执行 DDL 命令(包括 ALTER TABLE),不会自动提交未完成的事务。

精确说明

说法中的描述 在 PostgreSQL 中
“会先提交事务” 错误 - 不会自动提交
“再执行 ALTER” 错误 - ALTER 作为当前事务的一部分执行
整体说法 完全错误

验证示例

-- 开启事务
BEGIN;

-- 插入一条数据(未提交)
INSERT INTO users (name) VALUES ('张三');

-- 执行 ALTER TABLE(作为同一个事务的一部分)
ALTER TABLE users ADD COLUMN age INT;

-- 查看此时表数据
select * from users;
 name | age
------+-----
 张三 |
(1 row)

-- 此时可以回滚所有操作
ROLLBACK;

-- 检查结果:INSERT 和 ALTER 都被撤销了
SELECT * FROM users WHERE name = '张三';  -- 查不到,已回滚
 name
------
(0 rows)

\d users  -- age 列不存在,已回滚
                      Table "public.users"
 Column |         Type          | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
 name   | character varying(20) |           |          |

与 MySQL 的对比

特性 MySQL PostgreSQL
ALTER TABLE 是否自动提交未完成事务 ✅ 是 ❌ 否
DDL 是否可以回滚 ❌ 否(5.7及更早版本) ⚠️ 部分支持(8.0+的某些DDL) ✅ 是
事务中能否执行多个 DDL ❌ 每个 DDL 都会导致隐式提交 ✅ 可以,全部可回滚

PostgreSQL 的优势示例

BEGIN;

-- 多个 DDL 操作在一个事务中
ALTER TABLE users ADD COLUMN age INT;
ALTER TABLE users ADD COLUMN email VARCHAR(200);
CREATE INDEX idx_users_email ON users(email);
INSERT INTO users (name, age, email) VALUES ('李四', 25, 'li@example.com');

-- 发现某个操作有问题,全部回滚
ROLLBACK;
-- 所有表和索引都恢复到事务开始前的状态

需要注意的例外情况

PostgreSQL 中少数 DDL 操作不能放在事务中回滚:

  • CREATE/DROP DATABASE(数据库级操作)
  • CREATE/DROP TABLESPACE(表空间操作)
  • CREATE/DROP SUBSCRIPTION(逻辑复制订阅)
  • VACUUM、CLUSTER、REINDEX(某些维护操作,但 REINDEX 在事务中通常可以)
  • CREATE INDEX CONCURRENTLY(并发创建索引,不能放在事务块中)

但这些不包括普通的 ALTER TABLE

实际影响

  1. 更灵活:可以在一个事务中组合多个 DDL 和 DML 操作
  2. 更安全:出错了可以全部回滚,不会留下部分完成的状态
  3. 迁移友好:数据库结构变更可以作为原子操作执行

最佳实践

-- ✅ 推荐:显式事务控制
BEGIN;
  ALTER TABLE users ADD COLUMN age INT;
  ALTER TABLE users ADD COLUMN phone VARCHAR(20);
  UPDATE users SET phone = 'unknown' WHERE phone IS NULL;
COMMIT;  -- 或 ROLLBACK

-- ✅ 也可以单条执行(自动提交模式)
ALTER TABLE users ADD COLUMN address TEXT;  -- 自动提交,不可回滚

总结

  • 在 PostgreSQL 中:原说法完全错误。ALTER TABLE 不会自动提交未完成的事务,而是作为当前事务的一部分执行。
  • 与 MySQL 的关键区别:PostgreSQL 的事务支持更彻底,DDL 可以回滚;MySQL 的 DDL 会强制提交之前的事务。
  • 建议:在 PostgreSQL 中可以放心地在事务中使用 ALTER TABLE,这能提供更好的数据一致性和操作安全性。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐