如何在Java中实现ACID事务?

时间:2018-06-05 08:10:15

标签: java transactions

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

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

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

2 个答案:

答案 0 :(得分:2)

总的来说,这是不可能的。

文件系统不是一个交易资源(除非你有意识地和故意地在一个日志文件系统上),即使它们仍然存在要求它们可以与db事务一起参与2PC事务,在“外部”事务控制器下(谁可以引导和控制将需要的两阶段提交过程)。你的机会很小。

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

答案 1 :(得分:1)

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

但是,您仍然可以找到解决您必须解决的实际问题的解决方案。例如。通过将文件访问与数据库数据同步(存储文件名以及数据是否就绪)。

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

另一种更复杂的方法是通过文件系统锁定对数据的访问,因此当事务处理时,所有其他事务都被阻止读取和写入文件以及相应的数据库数据 at同一时间。例如。使用空锁文件(original-filename.lock)阻止其他人读取/写入该文件中的数据。这仅适用于与数据库数据具有一对一关系且未执行任何复杂查询的情况(在锁定数据时不应读取数据)。当然,只有在您控制访问文件或数据库的所有内容时,它才有效。它可能效率不高。您仍然需要为文件更改实现回滚机制(通常是复制重命名的东西)。

根据您的具体系统,还有其他几种解决方案或解决方法。这个问题可能“过于宽泛”。