2

在 oracle 10g 中,每个表的每个操作(插入、选择、更新、删除)都有一个存储过程。实际上,每个操作每个表可以有多个过程,例如在选择的情况下,它可以是 SelectList、SelectOneRecord、Search(使用动态查询)。

这些程序都没有事务。

有时我必须在一个事务中组合多个操作。例如,在一个表中插入并在另一个表中更新,都在一个事务中。为此,我制作了一个具有事务的单独程序。这个程序然后调用这两个程序。

为了在单个事务中启用上述组合过程调用,我没有在过程中放置​​任何事务行为,如上所述。

大多数时候我只需要执行一项操作,例如在一张表中插入。由于插入过程没有事务行为,因此我必须创建一个具有事务行为的单独过程,并且该过程调用插入过程。

我最终得到了许多基本程序(一张表,一项操作)和许多基本上是基本程序包装器的事务程序。

我的问题是,是否有某种方法可以在基本程序中具有条件事务行为。我的意思是一些 if 条件,我可以在其中放置事务逻辑,以便事务行为可以根据我传递的某些参数打开或关闭。然后当我只想做一个操作时,比如在一个表中插入,我调用带有事务行为的基本过程;而当我想在一个事务中调用两个过程,例如在一个事务中插入一个表并在另一个表中更新全部在一个事务中,然后我制作一个单独的事务过程并调用两个没有事务行为的基本过程。

以下是调用另一个过程并将其包装在事务中的事务过程:

BEGIN
    SAVEPOINT the_start;

    BasicProcedure(<list of parameters>);

    COMMIT;

    EXCEPTION
         WHEN OTHERS THEN

         BEGIN
             ROLLBACK TO the_start;
             RAISE;
         END;
END;

我可以很好地将保存点行和提交行放在 if 语句中,但我也可以将异常块放在 if 语句中。我必须将异常块放在 if 语句中吗?如果我在程序中捕获异常怎么办,当异常发生时它会自动回滚吗?

4

1 回答 1

6

您编写的内容称为 Table API。有些人对他们发誓,其他人则对他们进行诅咒。Table API 的案例基本上是:模块化和代码重用。反对的理由主要是性能:它们鼓励逐行或逐表处理,而定制的 SQL 连接会更有效。

我个人站在栅栏的两边。目前我更喜欢定制代码:它使交易更容易处理。

这让我想到了你的情况。表 API 应该是通用的并且在所有情况下都可用。这意味着他们无法控制事务的管理:这完全属于调用 Table API 方法的程序。这些程序是实现业务逻辑的代码:业务事务由许多构成工作单元的活动组成。所有这些都必须成功才能使事务成功,否则业务事务需要回滚。如果 Table API 命令发出它们自己的提交,随后的失败将使业务事务处于不一致的状态。 ACID适用于此级别以及单个 SL 级别。

这实际上与在其中编写带有定制 SQL 的存储过程没有什么不同。


“我不清楚你是否提倡制作业务逻辑事务存储过程。”

这是一个很大的领域,设计 PL/SQL 应用程序比业务逻辑要多。(如果你可以使用时间机器,你应该回到 Open World 2009 来观看我关于“使用 Intent 设计 PL/SQL”的演讲)

但从广义上讲,是的,PL/SQL 层的面向外部的方面应该由业务逻辑 API 组成,围绕工作单元(即业务事务)进行组织。

“这样的程序是自主交易吗?”

绝对不。自治事务仅适用于一个目的:记录和审计活动,我们需要永久记录所发生的事情,而不会影响更广泛的事务。该编译指示的任何其他用途都是等待发生的混乱或数据损坏错误。

商业交易是纯粹而简单的交易。存储过程应该拥有提交,或者他们应该将提交推迟到调用程序。

于 2012-06-30T21:05:02.797 回答