合 PG中的DDL支持回滚
简介
在Oracle或MySQL中,当执行到DDL语句时,会隐式的将当前回话的事务进行一次“COMMIT”操作,因此在MySQL或Oracle中执行DDL语句时,应该严格地将DDL和DML完全分开,不能混合在一起执行。
在PG中,多数DDL语句是可以被回滚的,但是有一些DDL语句例如CREATE INDEX CONCURRENTLY、CREATE DATABAE 、CREATE TABLESPACE等则不能回滚。
什么是Transactional DDL?
Transactional(事务)在关系型数据库是指一组SQL语句,要么提交,要么全部回滚。事务中包含的语句通常是DML语句,如INSERT、UPDATE、DELETE等。但是对于DDL语句呢?是否可以在事务中包含诸如CREATE、ALTER、DROP等DDL命令?
所谓Transactional DDL就是我们可以把ddl放到事务中,做到事务中的ddl语句要么全部提交,要么全部回滚。
Transactional DDL的好处
在进行一些模式升级等复杂工作时,可以利用此功能保护数据库。我们可以将所有更改都放入事务块中,确保它们都以原子方式应用,或者根本不应用。这大大降低了数据库因模式更改中的输入错误或其他此类错误而损坏数据库的可能性。
Oracle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | SYS@LHR11G> SET TRANSACTION NAME 't1'; Transaction set. SYS@LHR11G> create table aa(id int); Table created. SYS@LHR11G> select * from aa; no rows selected SYS@LHR11G> insert into aa values(1); 1 row created. SYS@LHR11G> select * from aa; ID ---------- 1 SYS@LHR11G> rollback; Rollback complete. SYS@LHR11G> select * from aa; no rows selected |
在Oracle的一个事务中,DDL语句不会被回滚。
MySQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | MySQL [lhrdb]> begin; Query OK, 0 rows affected (0.05 sec) MySQL [lhrdb]> MySQL [lhrdb]> create table bb(id int); Query OK, 0 rows affected (0.11 sec) MySQL [lhrdb]> rollback; Query OK, 0 rows affected (0.06 sec) MySQL [lhrdb]> select * from bb; Empty set (0.08 sec) MySQL [lhrdb]> begin; Query OK, 0 rows affected (0.05 sec) MySQL [lhrdb]> MySQL [lhrdb]> MySQL [lhrdb]> create table cc(id int); Query OK, 0 rows affected (0.64 sec) MySQL [lhrdb]> insert into cc values(1); Query OK, 1 row affected (0.05 sec) MySQL [lhrdb]> select * from cc; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.05 sec) MySQL [lhrdb]> rollback; Query OK, 0 rows affected (0.05 sec) MySQL [lhrdb]> select * from cc; Empty set (0.05 sec) |
在MySQL的一个事务中,DDL语句不会被回滚。
人大金仓的数据库和PG一样,都可以进行DDL回滚!