PL/SQL 存储过程是事务吗?

Mag*_*hio 5 sql database oracle stored-procedures transactions

PL/SQL 存储过程是事务吗?当触发器、过程或函数运行时,它是一个事务吗?我通常结束我的程序,COMMIT当发生错误时我使用ROLLBACK! 这是错的吗?

START TRANSACTION我不是在询问程序,但我想知道它们是否是交易。

谢谢你。

Rob*_*ijk 6

Are PL/SQL stored procedures transactions? When a trigger, procedure or function runs, is it a transaction?

否。事务从遇到的第一个 DML 开始,并在遇到 COMMIT 或 ROLLBACK 时结束。一个事务可以包含许多函数和过程调用以及 DML 语句和触发器代码。另一方面,您可以通过发出大量 COMMIT 来创建一个包含许多事务的过程。

I usually end my procedures with COMMIT and when an error occurs I use ROLLBACK! Is it wrong?

错误是一个强烈的词。我们只能说这不是一个好习惯。制作(打包的)函数和过程就是模块化:制作可重用的代码片段。当函数/过程包含 ROLLBACK 或 COMMIT 语句时,它停止可重用,因为它会弄乱调用者的事务。因此,最好不要在您的过程中使用 ROLLBACK 或 COMMIT 并将其留给最顶层的调用者。

您可以在整个代码中使用 SAVEPOINTS,以确保单个函数或过程不会留下事务的开放部分。但出于美学原因,我更喜欢不使用 SAVEPOINTS。对我来说,这只是五行不必要的代码,因为我知道我的调用者函数会很好地处理事务。

例外情况是当您创建一个自治过程时,根据定义,该过程是单个事务,因此需要以 COMMIT 结束。

更新

请注意,RAISE_APPLICATION_ERROR 或 RAISE [异常名称] 语句也将作为单个原子单元自动回滚您的 PL/SQL 块。这当然是一个理想的效果,因为它不会给您留下未提交的更改。

SQL> create table mytable (id int)
  2  /

Table created.

SQL> create procedure p
  2  as
  3  begin
  4    insert into mytable values (2);
  5    raise_application_error(-20000,'My exception');
  6  end;
  7  /

Procedure created.

SQL> select *
  2    from mytable
  3  /

no rows selected

SQL> insert into mytable values (1)
  2  /

1 row created.

SQL> exec p
BEGIN p; END;

*
ERROR at line 1:
ORA-20000: My exception
ORA-06512: in "X.P", regel 5
ORA-06512: in regel 1


SQL> select *
  2    from mytable
  3  /

        ID
----------
         1

1 row selected.
Run Code Online (Sandbox Code Playgroud)