官方文档-Transactions and Logical Units of Work
机译官方文档存储技术基础逻辑个人理解

对于日常逻辑来讲,事务意味着一个独立的过程,这个独立的过程就是这里的逻辑单元

必须在该单元内确保 数据完整性和正确性。例如:从 A 账户转账到 B 账户的时候,需要确保两个账户的数据同时生效,如果不能生效可能凭空丢失金额或凭空获得金额

数据库逻辑工作单元 LUW

确保数据一致性

从数据库编程的角度来看,数据库 LUW 是以数据库提交结束的不可分割的数据库操作序列。数据库 LUW 要么由数据库系统完全执行,要么根本不执行。成功执行数据库 LUW 后,数据库将处于一致状态。如果数据库 LUW 中发生错误,则自数据库 LUW 开始以来的所有数据库更改都将被撤消。这将使数据库处于事务开始之前的状态。

事务和逻辑单元 - 图1

在数据库 LUW 中发生的数据库更改在数据库提交之前实际上不会写入数据库。在此之前,您可以使用数据库回滚来撤消更改。在 SAP 系统中,可以隐式或使用显式命令触发数据库提交和回滚。

隐式数据库提交

一个工作进程只能执行单个数据库 LUW。这样做的结果是,当一个工作进程为用户或外部调用完成其工作时,它必须始终结束数据库 LUW。在以下情况下,工作流会触发隐式数据库提交:

  • 对话步骤完成时控制从工作流程到 SAP GUI 的更改。
  • 当在另一个工作进程 (RFC) 中调用函数模块时。控制传递到其他工作进程。
  • 当其他工作进程中的被调用函数模块 (RFC) 结束时。控件返回到调用工作进程。
  • WAIT 语句中断工作进程时。控制传递到另一个工作进程。
  • 对话步骤中的错误对话框(信息、警告或错误消息)。控制权从工作流程传递到 SAP GUI。

    显式数据库提交

    有两种方法可以在应用程序中触发显式数据库提交:

  • 调用函数模块DB_COMMIT此函数模块的唯一任务是启动数据库提交。

  • 使用 ABAP 语句 COMMIT WORK此语句启动数据库提交,但也执行其他任务(请参阅 COMMIT WORK 的关键字文档)。

    隐式数据库回滚

    以下情况会导致隐式数据库回滚:

  • 应用程序中的运行时错误每当应用程序由于不可预见的情况(例如,尝试除以零)而必须终止时,就会发生这种情况。

  • 终止消息终止消息是使用消息类型为 A 或 X 的 ABAP 语句 MESSAGE 生成的。在某些情况下(更新),它们也会使用消息类型 I、W 和 E 生成。这些消息结束当前应用程序。

    显式数据库回滚

    您可以使用 ABAP 语句 ROLLBACK WORK 显式触发数据库回滚。此语句启动数据库回滚,但也执行其他任务(请参阅 ROLLBACK WORK 的关键字文档)。
    从上面,我们可以绘制以下数据库LUW开始和结束的点列表。

    数据库 LUW 开始

  • 每次对话步骤启动时(当对话步骤发送到工作流程时)。

  • 每当以前的数据库 LUW 在数据库提交中结束时。
  • 每当以前的数据库 LUW 在数据库回滚中结束时。

    数据库 LUW 结束

  • 每次数据库提交发生时。这会将所有更改写入数据库。

  • 每次发生数据库回滚时。这将撤消 LUW 期间所做的所有更改。

    数据库 LUW 和数据库锁

    除了在其中所做的数据库更改外,数据库 LUW 还包含数据库锁。数据库系统使用锁来确保两个或多个用户不能同时更改相同的数据,因为这可能导致向数据库写入不一致的数据。数据库锁只能在数据库 LUW 期间处于活动状态。当数据库 LUW 结束时,它们将自动释放。为了对 SAP LUW 进行编程,我们需要 R/3 系统中的锁定机制,以允许我们创建具有更长使用寿命的锁(请参阅 SAP 锁定概念 )。

    SAP LUW

    SAP LUW 是对话步骤的逻辑单元,其更改将写入单个数据库 LUW 中

Open SQL 语句 INSERTUPDATEMODIFYDELETE 允许您对扩展为多个对话框步骤的数据库更改进行编程。即使尚未显式编程数据库提交,在处理屏幕后发生的隐式数据库提交也会结束数据库 LUW。下图显示了典型屏幕序列中的各个数据库 LUW:

事务和逻辑单元 - 图2

在此过程下,不能回滚前面的对话框步骤中的数据库更改。因此,它仅适用于各个对话步骤之间没有逻辑关系的程序。
但是,各个对话步骤中的数据库更改通常依赖于其他对话步骤中的数据库更改,因此必须一起执行或回滚所有数据库。这些依赖数据库更改形成逻辑单元,并且可以使用下面列出的捆绑技术分组到单个数据库 LUW 中。
由对话步骤组成的逻辑单元称为 SAP LUW,该逻辑单元的更改将写入单个数据库 LUW 中的数据库。与数据库 LUW 不同,SAP LUW 可以跨越多个对话步骤,并使用一系列不同的工作流程执行。如果 SAP LUW 包含数据库更改,则应将所有更改或根本不写入数据库。若要确保发生这种情况,必须在事务成功结束时包括数据库提交,以及在程序检测到错误时包括数据库回滚。但是,由于数据库 LUW 中的数据库更改无法在后续数据库 LUW 中撤消,因此必须在单个数据库 LUW 中对 SAP LUW 进行所有数据库更改。若要维护数据完整性,必须将所有数据库更改捆绑到 SAP LUW 的最终数据库 LUW 中。下图说明了此原则:

事务和逻辑单元 - 图3

SAP LUW 中数据库更改的捆绑技术可确保您仍然可以撤消这些更改。这还意味着,您可以将一个事务分布到多个工作流程中,甚至可以分布在多个 SAP 系统中。下面列出了在 SAP LUW 中捆绑数据库更改的可能性:
最简单的捆绑形式是在单个对话步骤中处理整个应用程序。在这里,系统检查用户的输入并更新数据库,而不会在对话步骤本身中发生数据库提交。当然,这并不适合复杂的业务流程。相反,SAP 系统包含以下捆绑技术。

使用功能模块进行捆绑更新

如果使用语句 CALL FUNCTION …在 更新任务 中,函数模块被标记为使用特殊的更新工作流程执行。这意味着您可以在函数模块中而不是在程序中为数据库更改编写 Open SQL 语句,并在程序中本来可以包含语句的位置调用函数模块。使用 IN UPDATE TASK 添加法调用函数模块时,该函数模块及其接口参数将作为日志条目存储在名为 VBLOG 的特殊数据库表中。
当程序到达 COMMIT WORK 语句时,使用更新工作流执行函数模块。在 COMMIT WORK 语句之后,对话框工作进程可以自由地接收进一步的用户输入。更新过程负责 SAP LUW 的更新部分。语句 COMMIT WORK 关闭程序对话部分的 SAP LUW 并启动更新。一旦更新过程提交或回滚了所有数据库更改,SAP LUW 即告完成。使用功能模块捆绑称为 更新
有关如何创建用于更新的功能模块的详细信息,请参阅为数据库更新创建函数模块
在更新过程中,错误仅在异常 cass 中发生,因为系统会在 SAP LUW 的对话框阶段检查所有逻辑错误,例如不正确的条目。如果发生逻辑错误,程序可以使用 ROLLBACK WORK 语句终止更新。然后,不调用函数模块,并从表 VBLOG 中删除日志条目。更新本身期间的错误通常是技术性的,例如内存不足。如果发生技术错误,更新过程将触发数据库回滚,并将日志条目放回 VBLOG 中。然后,它会向其对话框最初生成 VBLOG 条目的用户发送一封邮件,其中包含终止的详细信息。系统管理员必须更正这些错误。在此之后,可以再次处理返回的 VBLOG 条目。
有关更新管理的详细信息,请参阅更新管理
这种在 SAP LUW 的最后一个数据库 LUW 中捆绑数据库更改的技术允许您异步更新数据库。这样可以减少对话过程中的响应时间。例如,可以将更新与对话框工作进程完全分离,并在远程数据库服务器上使用中央更新工作进程。

使用子例程捆绑

The statement PERFORM ON COMMIT calls a subroutine in the dialog work process. However, it is not executed until the system reaches the next COMMIT WORK statement. Here, as well, the ABAP statement COMMIT WORK defines the end of the SAP LUW, since all statements in a subroutine called with PERFORM ON COMMIT that make database changes are executed in the database LUW of the corresponding dialog step.

事务和逻辑单元 - 图4

这种捆绑技术对 CALL FUNCTION … IN UPDATE TASK 的优点是性能更好,因为更新数据不必写入额外的表中,因此减少了数据库访问量。但是,缺点是无法在 PERFORM 中传递参数…ON COMMIT 语句。使用全局变量和 ABAP 内存传递数据。使用此方法传递数据时,存在相当大的数据不一致危险。

在其他 SAP 系统中使用功能模块捆绑使用

使用调用函数调用的函数模块 …在后台中,当程序到达下一个 COMMIT WORK 语句(使用远程函数调用)时,将注册任务目标以在另一个 SAP 系统中后台执行。在 提交工作 之后,对话进程不会等待这些函数模块被执行(异步更新)。以这种方式注册的所有函数模块都在单个数据库 LUW 中一起执行。例如,当您需要在多个数据库中维护相同的数据时,这些更新非常有用。
有关更多详细信息,请参阅关键字文档。
有关 RFC 处理的更多详细信息,请参阅基础服务文档的远程通信部分。

SAP事务

SAP 事务是你开始使用事务代码或ABAP程序,可能包含 一个或多个 SAP LUW

SAP LUW 是一个由对话步骤组成的逻辑单元,其更改将写入单个数据库 LUW 中的数据库。在应用程序中,使用 COMMIT WORKROLLBACK WORK 语句结束 SAP LUW。SAP 事务是您开始使用事务代码的 ABAP 应用程序。它可能包含一个或多个 SAP LUW。每当系统到达不在 SAP 事务的最后一个对话步骤末尾的 COMMIT WORK 或 ROLLBACK WORK 语句时,它就会打开一个新的 SAP LUW。
如果特定应用程序要求您编写复杂的事务,则将 SAP 事务中的逻辑进程排列成一系列单独的 SAP LUW 通常很有用。您可以按如下方式构建 SAP 事务:

  • 使用一个或多个 SAP LUW。这种形式的事务完全由处理块(对话框模量、事件块、函数模块调用和子例程)组成。应小心确保外部子例程或函数模块不会导致意外执行 COMMIT WORKROLLBACK WORK 语句。
  • 通过插入 SAP LUWABAP 语句调用事务(启动新事务)、SUBMIT 语句(启动可执行程序)和调用函数 …目标(使用 RFC 调用函数模块)打开一个新的 SAP LUW。当您调用某个程序时,它始终会打开自己的 SAP lUW。但是,它不会结束调用它的 SAP 事务的 LUW。这意味着 COMMIT WORKROLLBACK WORK 语句仅适用于被调用程序的 SAP LUW。当新的 LUW 完成时,系统将继续处理第一个 SAP LUW。
  • 通过并行运行两个 SAP LUW调用函数 …START NEW TASK 语句在新会话中异步调用函数模块。与正常的函数模块调用不同,调用事务在函数模块启动后立即进行自己的处理,并且不会等待它完成处理。函数调用是异步的。被调用的函数模块现在可以调用自己的屏幕并与用户交互。