【问题标题】:Transaction mode for file operations in JavaJava中文件操作的事务模式
【发布时间】:2009-08-21 09:58:03
【问题描述】:

也许我在这里试图解释的内容没有任何意义,所以我想提前道歉。不管怎样,我会努力的。

我正在尝试从文件中读取,执行一些数据库操作并将内容移动到另一个文件。我想知道是否可以在 Java 中以原子方式执行所有这些操作,因此如果操作列表中出现任何问题,请回滚完整序列并返回起点。

提前感谢您的帮助。

【问题讨论】:

    标签: java transactions


    【解决方案1】:

    看看Apache Commons Transaction。它具有以事务方式管理文件的能力。

    archived article 详细介绍了它与文件系统的用途。

    更新

    请注意首页上的状态显示:

    我们决定将项目移至休眠状态,因为我们确信无法可靠地实现主要宣传的事务文件访问功能。我们确信,在普通文件系统之上不可能有这样的实现。尽管还有其他有用的部分(如多级锁定,包括死锁检测),但事务文件系统是人们使用这个库的主要原因。因为它根本无法完全交易,所以它不像宣传的那样工作。

    【讨论】:

    • 文章不再可用
    • 嗨,Brian Agnew,您能给这篇文章提供新链接吗
    • 我没有,我承认。 Google 的缓存或许能帮到您
    • 我正在添加一个存档链接(感谢@Daniel Wagner 在其他地方建议该链接)。
    • 如果您现在查看链接,该项目处于“休眠”状态,因为“它根本无法完全交易,它不像宣传的那样工作”。在不查看 API 的情况下,我的解释是他们试图允许非冲突事务之间的并发。如果您使用完整的序列化(或至少在整个目标文件系统上使用 rwlock),我认为这将非常简单。但它不会是一个非常大的库,而且它显然会限制它适用的吞吐量/可扩展性。
    【解决方案2】:

    没有标准的事务文件 API,但我相信有一个 Apache 项目可以实现您想要的。

    http://commons.apache.org/transaction/file/index.html

    事务文件包为您提供了允许您在任何文件系统上进行原子读写操作的代码。文件资源管理器为您提供了在事务中隔离对一组文件的许多操作的可能性。使用 locks 包,它能够为您提供完整的 ACID 事务,包括可序列化性。当然,要完成这项工作,对托管文件的所有访问都必须由该管理员完成。对文件系统的直接访问不能被管理器监控。

    更新

    请注意首页上的状态显示:

    我们决定将项目移至休眠状态,因为我们确信无法可靠地实现主要宣传的事务文件访问功能。我们确信,在普通文件系统之上不可能有这样的实现。尽管还有其他有用的部分(如多级锁定,包括死锁检测),但事务文件系统是人们使用这个库的主要原因。因为它根本无法完全交易,所以它不像宣传的那样工作。

    【讨论】:

      【解决方案3】:

      XADisk 支持文件系统上的 XA 事务,它应该可以解决您的问题。它可以与数据库和其他 XA 资源一起参与 XA 事务。

      如果您的应用程序不在支持 JCA 的环境中,您还可以使用独立的事务管理器(如 Atomikos)并执行涉及文件(使用 XADisk)和数据库的 XA 事务。

      更新

      该项目的主页已不存在,Maven 上的最后一次发布是在 2013 年。

      【讨论】:

      • 看起来不错。你有任何参考资料,项目,谁使用你的作品?您有来自用户的反馈吗?
      • @Gábor - 你可以在这里找到一些stories/feedbacks
      【解决方案4】:

      不,至少不是通过简单的调用。一般的文件系统(尤其是 Java 文件系统操作)不支持“回滚”。

      但是你可以效仿这个。一种常见的方法是首先重命名文件,以便将其标记为“正在处理”。例如,附加一些后缀。

      然后处理它,然后更改文件。如果出现任何问题,只需回滚数据库,将所有带后缀的文件重命名为原始名称即可。

      作为奖励,在某些 FS 上,重命名甚至是原子的,因此即使并发更新也很安全(不知道这是否与您相关)。我不知道文件重命名在 Java 中是否是原子的;你需要检查一下。

      【讨论】:

      • 这似乎是一个非常直接的解决方案。我喜欢 KISS 选项,所以我会尝试一下。
      • 这不处理文件写入出错的情况。在这种情况下,只需重命名它将保留现在可能损坏的文件
      【解决方案5】:

      您可以使用Two-Phase Commit 协调分布式事务。然而,这实现起来相当复杂,我经常看到采用的一种方法是使用单阶段提交,构建一堆事务,然后快速连续提交它们,如果其中一个提交尝试失败,则会生成错误,但是其他人成功。

      如果您选择实施两阶段提交,则需要为事务中的每个参与者提供Write-Ahead Logging,您可以在其中记录操作,然后再进行操作,从而允许您在事务失败时回滚任何更改。例如,您需要这样做才能潜在地撤消对文件所做的任何更改(如 sleske 所述)。

      【讨论】:

        【解决方案6】:

        JBossTS 为transactional file i/o 提出了自己的实现,作为Narayana 项目(以前称为JBossTS)的一部分。

        【讨论】:

          猜你喜欢
          • 2020-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-18
          相关资源
          最近更新 更多