【问题标题】:Oracle Transaction CommitOracle 事务提交
【发布时间】:2019-12-09 05:23:35
【问题描述】:

假设我有一个执行大量 CRUD 操作的函数,并假设该函数将毫无例外地执行(100% 成功)。为整个函数或每个 CRUD 操作提交事务是否更好。基本上,我想知道在执行具有大量 CRUD 操作的函数时,使用许多事务提交是否会对内存和时间消耗产生影响。

【问题讨论】:

    标签: oracle spring-transactions


    【解决方案1】:

    事务边界应由您的业务逻辑定义。

    如果您的应用程序有 100 个 CRUD 操作要执行,并且每个操作都完全独立于其他操作,那么每个之后的提交可能是合适的。想一想:对您的数据库运行报告的用户只看到一半的 CRUD 操作是否可以?

    事务是一组必须同时发生或根本不发生的更新,因为部分事务将代表不一致或不准确的状态。

    在每笔交易结束时提交 - 就是这样。不多也不少。它与性能、释放锁或管理服务器资源无关。这些都是真正的技术问题,但你不能通过在一个逻辑工作单元中提交来解决它们。提交频率不是有效的“调整技巧”。

    编辑

    回答您的实际问题:

    基本上,我想知道在执行具有大量 CRUD 操作的函数时,使用许多事务提交是否会影响内存和时间消耗。

    频繁提交实际上会减慢您的速度。每次执行常规提交时,Oracle 都必须确保重做日志缓冲区中的任何内容都刷新到磁盘,并且您的 COMMIT 将等待该过程完成。

    此外,频繁提交很少或根本没有节省内存。几乎所有事务的工作和任何持有的锁都被写入内存中的重做日志缓冲区和/或数据库块缓冲区。为了管理内存,Oracle 会在后台尽可能频繁地将这两个刷新到磁盘。是的,没错——你的脏的、未提交的数据库块可以写入磁盘。无需提交。

    真正巨大的交易唯一可能耗尽的资源是 UNDO 空间。但是,再一次,你不能通过提交逻辑工作单元的一半来解决这个问题。如果您的逻辑工作单元真的那么大,请使用适当数量的 UNDO 空间来调整您的数据库。

    【讨论】:

    • 我完全同意你的看法。但是对于一个可以从停止点重新开始的工作,如果中间出现异常,我们不必每次都从头开始对吗?但我担心内存和时间的使用。
    • 如果您的 100 个 CRUD 操作中只有 50 个可以提交并在您的应用程序、报告等中可见,那么听起来您有 100 个事务。如果不行,那么听起来你有 一个 事务,在这种情况下,别无选择,只能在每次中间出现异常时从头开始。这就是人们表演事物的原因之一。假设您正在加载一个文件并且整个文件是一个事务。如果将其暂存,则可以将每个 CRUD 提交到暂存表,然后将真实表作为单个事务进行更新。
    • 现在我只有一个更高级别的交易。我一直强调时间的原因是因为其中一个删除需要更长的时间并且它正在超时。我喜欢拆分交易,看看是否能解决问题。
    【解决方案2】:

    我的回答是“视情况而定”。事务是只涉及一张表还是多张表中的数据?您是在执行插入、更新还是删除。使用 INSERT 没有其他会话可以看到您的数据,直到它被提交,所以技术上不急。但是,如果您更新表上的一行,其中完全相同的行可能需要由另一个会话在短时间内更新,您不希望保留该行的时间超过绝对必要的时间。什么构成工作逻辑单元,涉及的表和索引更改消耗了多少 UNDO,以及对相同行的并发 DML 需求都在选择提交频率时发挥作用。

    【讨论】:

    • 所有操作都是删除,并且来自不同的表。我也按照命令执行这些删除。
    • 大力水手,如果行之间存在父子关系,那么我希望您在同一事务中删除父子关系,以在进程中断的情况下保持数据一致性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2011-07-12
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    相关资源
    最近更新 更多