gpt4 book ai didi

design-patterns - "atomicity"一系列操作如何实现? (不一定与多线程相关)

转载 作者:行者123 更新时间:2023-12-02 09:30:34 24 4
gpt4 key购买 nike

问题

我的程序有一个操作,它由一系列更改全局状态的单个操作组成。每个基本操作都可能失败并使全局状态处于未定义状态。

问题

是否有一种通用模式可以帮助我使组合操作成为“原子”操作,即如果其中一个子操作失败,则全局状态保持不变?

我使用 C++,因此如果答案包含代码,如果可以选择,请选择该语言。但我不介意其他语言的例子。

评论

  • 这类似于数据库的“原子性”,在提交时您可以添加所有内容或不添加任何内容。这是如何实现的?

  • 就我而言,我的全局状态是文件系统的状态。我需要一次添加或删除多个文件,并希望确保它们全部添加或未添加任何内容。

我的想法

我能想到的最好的办法是一个获取操作及其逆操作列表的类。如果任何操作失败,则执行已执行操作的相反操作。但是如果其中一个逆向操作失败怎么办?

该类的接口(interface)是什么样的?我会有一个类似于可逆操作的额外类吗?您知道我可以在哪里阅读有关此问题的更多信息吗?

最佳答案

基本的解决方案是提交或回滚。

通用的 C++ 实现是构建支持 3 种方法的对象列表:

  • run()它将执行所有可能失败的步骤,而不会产生可见副作用。如果失败,它必须在不改变任何内容的情况下抛出
  • commit()它可能不会抛出,并且只能使 run() 期间执行的步骤可见
  • rollback()它可能不会抛出,并且只能撤消 run() 期间执行的步骤

然后迭代该列表调用 run()在一切事情上。如果有任何抛出,捕获它并 rollback()成功运行的一切。如果没有抛出,commit()他们全部。


适合您情况的大致工作流程是 - 对于每个文件创建对象:

  1. 调用 run()在正确的目录中创建(并填充?)文件,但使用临时名称 - 最好隐藏

    • 如果失败,请调用rollback()成功 run()文件创建对象。这必须删除临时文件并且可能不会失败。

      然后,放弃,从头开始重试,提示用户什么的。

  2. 重复#1,直到创建完所有文件
  3. 他们都成功了,所以请调用commit()在每个对象上。这必须将临时文件重命名为其最终名称,并且可能不会失败

这要求 commit步骤不能失败。在这种情况下,假设重命名文件不会失败 - 在您到达 commit 之前,您必须确保这是真的(即不存在名称冲突)阶段。


请注意,这确实有中间的非原子更改 - 一般来说,避免这种情况的唯一方法是拥有全局状态的两个副本,以及一个原子交换来提交修改后的状态。一般来说,即使您正在编写驱动程序,您也不能对文件系统执行此操作。

关于design-patterns - "atomicity"一系列操作如何实现? (不一定与多线程相关),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33548463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com