PostgreSQL的隐式提交
·
接上一篇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。
实际影响
- 更灵活:可以在一个事务中组合多个 DDL 和 DML 操作
- 更安全:出错了可以全部回滚,不会留下部分完成的状态
- 迁移友好:数据库结构变更可以作为原子操作执行
最佳实践
-- ✅ 推荐:显式事务控制
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,这能提供更好的数据一致性和操作安全性。
更多推荐
所有评论(0)