代码之家  ›  专栏  ›  技术社区  ›  rico

Java中如何实现酸性事务?

  •  0
  • rico  · 技术社区  · 8 年前

    我必须执行两个操作,一个将数据保存在数据库中,一个将字节保存在文件系统中,我希望这两个操作以原子方式执行。 基本上,如果action 1失败,整个过程就会失败,如果action 2失败,同样的thing和db action也会回滚。

    public void doAction() {
       this.saveData();
       this.saveFile();
    }
    

    如何在Java中执行涉及数据库和文件系统的ACTION事务?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Erwin Smout    8 年前

    总的来说这是不可能的。

    文件系统不是事务性资源(除非您有意识地、故意地使用日志文件系统或其他文件系统),即使它们是事务性资源,也仍然要求它们可以在“外部”事务控制下参与2PC事务和DB事务。ER(能够指导和控制所需的两阶段提交过程)。你的机会很渺茫。

    你可以自己尝试做各种各样的事情,例如记录任何文件(或文件部分)的预写状态,但基本上你是自己重新创建一个日志文件系统,除非你完全完全地这样做(不是一个容易的任务),否则你的系统仍然会有(严重的)上面有洞。

        2
  •  1
  •   Stefan Steinegger    8 年前

    酸不仅需要能够 回滚更改 当其中一个操作失败时,它还需要 隔离 从其他交易。一旦将数据存储到文件中,其他人就可以看到更改。在之前或之后提交数据库都违反了ACID规则。

    然而,你仍然可以找到解决实际问题的方法。例如,将文件访问与数据库数据同步(例如,存储文件名和数据是否准备就绪)。

    还可以考虑将数据存储在blob而不是文件中。

    另一种更复杂的方法是通过文件系统锁定对数据的访问,因此当一个事务正在写入时,所有其他事务都将被阻止读取和写入该文件 以及相应的数据库数据 同时。例如,使用一个空的锁文件(原始文件名.lock),阻止其他人读/写该文件中的数据。只有在与数据库数据有1对1关系并且没有执行任何复杂查询(在锁定数据时不应读取数据)时,此方法才有效。当然,只有当您控制了访问文件或数据库的所有内容时,它才起作用。可能效率不高。您仍然需要实现文件更改的回滚机制(通常是复制重命名内容)。

    根据您的特定系统,还有一些其他解决方案或解决方案。这个问题可能“太宽泛了”。