我们为什么要在sql中明确使用回滚?

时间:2014-12-02 08:38:46

标签: sql postgresql

我正在使用PostgreSQL 9.3

我对交易及其运作方式存在一种误解。假设我们在事务中包装了一些SQL运算符,如下所示:

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

如果出现问题,交易将自动回滚。考虑到这一点我无法明确何时使用ROLLBACK?你能在必要时得到一个例子吗?

2 个答案:

答案 0 :(得分:7)

在PostgreSQL中,事务 not 会在出错时自动回滚。

它被设置为中止状态,其中进一步的命令将失败并出现错误,直到您回滚事务为止。

观察:

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

......不用说,这可能会让你感到非常沮丧。

答案 1 :(得分:1)

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

  • 对数据进行一些更改(UPDATEDELETE ...)。
  • 运行SELECT语句以检查数据修改的结果。
  • 如果结果不符合预期,请ROLLBACK

在Postgres DB中,您甚至可以使用DDL语句(CREATE TABLE,...)

执行此操作