Java中文件操作的事务模式
也许我在这里试图解释的内容没有任何意义,所以我想提前道歉。无论如何,我会尝试。
我正在尝试从文件中读取数据,执行一些数据库操作并将内容移动到另一个文件。我想知道是否可以在 Java 中以原子方式执行所有这些操作,因此如果操作列表中出现任何问题,请回滚完整序列并返回到起点。
预先感谢您的帮助。
Perhaps what I'm trying to explain here doesn't make any sense, so I'd like to apologize in advance. Anyway, I will try.
I'm trying to read from a file, perform some database operations and move the content to another file. I was wondering if it is possible to perform all this operations in an atomic way in Java, so if anything goes wrong in the list of actions, rollback the complete sequence and go back to the start point.
Thanks in advance for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
查看 Apache Commons 事务。它具有以事务方式管理文件的能力。
一篇存档文章详细介绍了其使用文件系统。
更新
请注意,首页上的状态显示:
Take a look at Apache Commons Transaction. It has the capability to manage files transactionally.
An archived article detailed its use with the file system.
update
Be aware that the status on the front page says:
没有标准的事务文件 API,但我相信有一个 Apache 项目可以实现您想要的功能。
http://commons.apache.org/transaction/file/index.html
更新
请注意,首页上的状态显示:
There is no standard Transaction File API however I beleive that there is an Apache project that implements what you want.
http://commons.apache.org/transaction/file/index.html
update
Be aware that the status on the front page says:
由于 XADisk 支持文件系统上的 XA 事务,它应该可以解决您的问题。它可以与数据库和其他 XA 资源一起参与 XA 事务。
如果您的应用程序不在 JCA 支持环境中,您还可以使用独立事务管理器(如 Atomikos)并执行涉及文件(使用 XADisk)和数据库的 XA 事务。
更新
该项目的主页不再存在,Maven 上的最后一个版本是在 2013 年。
As XADisk supports XA transactions over file-systems, it should solve you problem. It can participate in XA transactions along with Databases and other XA Resources.
In case your application is not in a JCA supportive environment, you can also use standalone Transaction Manager like Atomikos and carry out XA transactions involving both files (using XADisk) and Database.
update
The project's home page does not exist anymore and the last release on Maven was in 2013.
不,至少不是通过简单的调用。一般的文件系统(特别是 Java 文件系统操作)不支持“回滚”。
不过你可以模仿这个。一种常见的方法是首先重命名文件,以便将其标记为“正在处理”。例如附加一些后缀。
然后处理它,然后更改文件。如果出现任何问题,只需回滚数据库,将所有带后缀的文件重命名回原来的名称即可。
作为奖励,在某些 FS 上,重命名甚至是原子的,因此即使并发更新也是安全的(不知道这是否与您相关)。我不知道文件重命名在Java中是否是原子的;你需要检查一下。
No, at least not with a simple call. Filesystems in general (and Java filesystem operations in particular) do not support a "rollback".
You could however emulate this. A common way would be to first rename the file so that it is marked as being "in processing". Append some suffix for example.
Then process it, then change the file. If anything goes wrong, just rollback the DB, rename all the file(s) with suffixes back to their original names and you're set.
As a bonus, on some FS a rename is even atomic, so you'd be safe even with concurrent updates (don't know if this is relevant for you). I do not know whether file renaming is atomic in Java though; you'd need to check.
您可以使用两阶段提交来协调分布式事务。然而,这实现起来相当复杂,我经常看到的一种方法是使用单阶段提交,构建事务堆栈,然后快速连续地全部提交它们,如果其中一个提交尝试失败,则会生成错误,但其他人成功了。
如果您选择实施两阶段提交,则需要为每个参与者预写日志记录在事务中,您可以在执行操作之前记录这些操作,这样您就可以在事务失败时回滚任何更改。例如,您需要执行此操作才能撤消对文件所做的任何更改(如 sleske 提到的)。
You can coordinate a distributed transaction using Two-Phase Commit. However, this is fairly complex to implement and an approach I've often seen taken is to use single-phase commit, building a stack of transactions and then committing them all in quick succession, generating an error if one of the commit attempts fails but others succeed.
If you chose to implement Two-Phase Commit you'd require Write-Ahead Logging for each participant in the transaction, where you log actions before you've taken them, allowing you to roll back any changes if the transaction fails. For example, you'd need to do this in order to potentially reverse any changes made to files (as sleske mentions).
JBossTS 提出了自己的事务文件 i/o 实现,作为Narayana 项目(以前称为 JBossTS)。
JBossTS proposes its own implementation for transactional file i/o, as part of the Narayana project (formerly called JBossTS).