也许我在这里要解释的没有任何意义,所以我想提前道歉。无论如何,我会尝试。
我正在尝试从文件中读取,执行一些数据库操作并将内容移动到另一个文件。我想知道是否可以在Java中以原子方式执行所有这些操作,因此如果操作列表中出现任何问题,则回滚整个序列并返回起点。
提前感谢您的帮助。
答案 0 :(得分:30)
看看Apache Commons Transaction。它具有以事务方式管理文件的能力。
archived article详细说明了它与文件系统的使用。
请注意首页上的状态为:
我们决定将项目移至休眠状态,因为我们确信主要广告功能事务文件访问无法可靠地实现。我们相信,在普通文件系统之上不可能实现这样的实现。虽然还有其他有用的部分(如多级锁定,包括死锁检测),但事务文件系统是人们使用此库的主要原因。因为它根本无法完全交易,所以它不像宣传的那样有效。
答案 1 :(得分:8)
没有标准的事务文件API,但我相信有一个Apache项目可以实现你想要的。
http://commons.apache.org/transaction/file/index.html
事务性文件包为您提供了允许您对任何文件系统进行原子读写操作的代码。文件资源管理器使您可以隔离事务中一组文件的多个操作。使用锁定包,它可以为您提供完整的ACID事务,包括可序列化。当然,为了使这项工作,所有对托管文件的访问必须由该管理器完成。管理员无法监控对文件系统的直接访问。
请注意首页上的状态为:
我们决定将项目移至休眠状态,因为我们确信主要广告功能事务文件访问无法可靠地实现。我们相信,在普通文件系统之上不可能实现这样的实现。虽然还有其他有用的部分(如多级锁定,包括死锁检测),但事务文件系统是人们使用此库的主要原因。因为它根本无法完全交易,所以它不像宣传的那样有效。
答案 2 :(得分:7)
由于XADisk支持文件系统上的XA事务,它应该可以解决您的问题。它可以与数据库和其他XA资源一起参与XA事务。
如果您的应用程序不在JCA支持环境中,您还可以使用独立的事务管理器(如Atomikos)并执行涉及这两个文件(使用XADisk)和数据库的XA事务。
项目的主页不再存在,Maven的最后一个版本是在2013年。
答案 3 :(得分:4)
不,至少不是简单的电话。一般的文件系统(特别是Java文件系统操作)不支持“回滚”。
然而,你可以效仿这一点。一种常见的方法是首先重命名文件,使其标记为“处理中”。例如,附加一些后缀。
然后处理它,然后更改文件。如果出现任何问题,只需回滚数据库,将带有后缀的所有文件重命名为原始名称即可。
作为奖励,在某些FS上,重命名甚至是原子的,所以即使是并发更新你也是安全的(不知道这是否与你相关)。我不知道文件重命名在Java中是否是原子的;你需要检查一下。
答案 4 :(得分:3)
您可以使用Two-Phase Commit协调分布式事务。但是,这实现起来相当复杂,我经常看到的方法是使用单阶段提交,构建一堆事务,然后快速连续地提交它们,如果其中一个提交尝试失败,则会生成错误但是其他人都成功了。
如果您选择实施两阶段提交,则您需要为事务中的每个参与者Write-Ahead Logging,在您执行操作之前记录操作,如果事务失败,您可以回滚任何更改。例如,您需要执行此操作以便可能撤消对文件所做的任何更改(如sleske所述)。
答案 5 :(得分:3)
作为transactional file i/o项目(以前称为JBossTS)的一部分,JBossTS为Narayana提出了自己的实现。