2014-12-02 21 views
2

我使用PostgreSQL 9.3为什么我们应该明确地在sql中使用回滚?

我对交易以及它们是如何工作有一个误解。假设我们在如下事务中包装了一些SQL运算符:

BEGIN; 
    insert into tbl (name, val) VALUES('John', 'Doe'); 
    insert into tbl (name, val) VALUES('John', 'Doee'); 
COMMIT; 

如果出现问题,交易将自动回滚。考虑到这一点,我不能明确什么时候应该使用ROLLBACK?有必要的时候可以举个例子吗?

回答

5

在PostgreSQL中,交易是而不是自动回滚出错。

它被设置为中止状态,在此状态下,进一步的命令将失败并出现错误,直到您将事务重新传回。

观察:

regress=> BEGIN; 
BEGIN 
regress=> LOCK TABLE nosuchtable; 
ERROR: relation "nosuchtable" does not exist 
regress=> SELECT 1; 
ERROR: current transaction is aborted, commands ignored until end of transaction block 
regress=> ROLLBACK; 
ROLLBACK 

这一点很重要,因为它可以防止您意外执行一半的交易。试想一下,如果PostgreSQL自动回滚,允许发生新的隐式交易,而你试图运行下面的语句序列:

BEGIN; 
INSERT INTO archive_table SELECT * FROM current_tabble; 
DELETE FROM current_table; 
COMMIT; 

PostgreSQL将当它看到错字current_tabble中止交易。所以DELETE不会发生 - 所有语句错误后会被忽略,而COMMIT被视为ROLLBACK用于中止的事务:

regress=> BEGIN; 
BEGIN 
regress=> SELECT typo; 
ERROR: column "typo" does not exist 
regress=> COMMIT; 
ROLLBACK 

如果它,而不是自动回滚事务回来,它会像你跑:

BEGIN; 
INSERT INTO archive_table SELECT * FROM current_tabble; 
ROLLBACK; -- automatic 
BEGIN; -- automatic 
DELETE FROM current_table; 
COMMIT; -- automatic 

......不用说,可能会让你很不高兴。

+0

很好的解释 – Matt 2014-12-02 08:52:53

+0

为什么最后一次提交您的最后一个例子自动? – 2014-12-02 09:17:15

+0

@ St.Antario如果没有明确的'BEGIN',PostgreSQL以自动提交模式运行语句。 – 2014-12-02 09:18:10

0

显式ROLLBACK其他用途手动修改和测试案例:

  • 做一些更改数据(UPDATEDELETE ...)。
  • 运行SELECT用于检查数据修改结果的语句。如果结果不符合预期,则执行ROLLBACK

在Postgres的数据库,你甚至可以使用DDL语句做到这一点(CREATE TABLE,...)

相关问题