在Oracle中,当SQL命令中出现运行时错误时,将回滚该单个命令所引起的数据库上的所有更新。这称为语句级别事务隔离。例如,如果单个UPDATE命令成功更新五行,但尝试更新第六行时出现异常,则将回滚此UPDATE命令对所有六行进行的更新。之前尚未提交或回滚的SQL命令的效果将挂起,直到执行了COMMIT或ROLLBACK命令。

在PostgreSQL中,如果在执行SQL命令时发生异常,则将回滚自事务开始以来的数据库上的所有更新。此外,该事务停留在中止状态,必须发出COMMIT或ROLLBACK命令,才能开始其他事务。

如果polar_comp_stmt_level_tx设置为TRUE,则异常不会自动回滚之前未提交的数据库更新,这模拟Oracle行为。如果polar_comp_stmt_level_tx设置为FALSE,则异常将回滚未提交的数据库更新。

注意 仅在绝对必要时才使用设置为TRUE的polar_comp_stmt_level_tx,因为这可能会对性能造成负面影响。

在PSQL中运行的以下示例显示当polar_comp_stmt_level_tx为FALSE时,第二个INSERT命令中止还会回滚第一个INSERT命令。请注意,在PSQL中,必须发出命令\set AUTOCOMMIT off,否则每个语句会自动提交,违背了此polar_comp_stmt_level_tx的效果演示的目的。

\set AUTOCOMMIT off
SET polar_comp_stmt_level_tx TO off;

INSERT INTO emp (empno,ename,deptno) VALUES (9001, 'JONES', 40);
INSERT INTO emp (empno,ename,deptno) VALUES (9002, 'JONES', 00);
ERROR:  insert or update on table
"emp" violates foreign key constraint "emp_ref_dept_fk"
DETAIL:  Key (deptno)=(0) is not present in table "dept".

COMMIT;
SELECT empno, ename, deptno FROM emp WHERE empno > 9000;

empno | ename | deptno
-------+-------+--------
(0 rows)        

在 polar_comp_stmt_level_tx 设置为 TRUE 的以下示例中,在第二个 INSERT 命令出错后,尚未回滚第一个 INSERT 命令。此时,可以提交或回滚第一个 INSERT 命令。

\set AUTOCOMMIT off
SET polar_comp_stmt_level_tx TO on;

INSERT INTO emp (empno,ename,deptno) VALUES (9001, 'JONES', 40);
INSERT INTO emp (empno,ename,deptno) VALUES (9002, 'JONES', 00);
ERROR:  insert or update on table
"emp" violates foreign key constraint "emp_ref_dept_fk"
DETAIL:  Key (deptno)=(0) is not present in table "dept".

SELECT empno, ename, deptno FROM emp WHERE empno > 9000;

empno | ename | deptno
-------+-------+--------
  9001 | JONES |     40
(1 row)

COMMIT;       

可能已发出 ROLLBACK 命令而非 COMMIT 命令,在这种情况下,还已回滚员工编号 9001 的插入。