43

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.

Giroscopio
  • 433
  • 1
  • 4
  • 6

6 Answers6

31

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:

We have decided to move the project to dormant as we are convinced that the main advertised feature transactional file access can not be implemented reliably. We are convinced that no such implementation can be possible on top of an ordinary file system. Although there are other useful parts (as multi level locking including deadlock detection) the transactional file system is the main reason people use this library for. As it simply can not be made fully transactional, it does not work as advertised.

Lion
  • 3
  • 2
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • The article is not available any more – David Rabinowitz Jan 05 '11 at 09:45
  • hi, Brian Agnew ,could you give new link for this article,please – sergionni Jan 11 '11 at 15:37
  • I don't have one, I confess. Google's cache may be able to help you – Brian Agnew Jan 11 '11 at 18:26
  • 2
    I'm adding an archive link (thanks @Daniel Wagner for suggesting the link, elsewhere). – Mu Mind Jul 15 '11 at 12:33
  • 10
    If you look at the link _now_, that project is "dormant" because "it simply can not be made fully transactional, it does not work as advertised". Without looking at the API, my interpretation is they were trying to allow concurrency between non-conflicting transactions. If you used complete serialization (or at least an rwlock on the whole target filesystem), I think it would be pretty straightforward. But it wouldn't be a very big library, and it would obviously limit the throughput / scalability that it would be appropriate to use for. – sourcejedi May 09 '13 at 13:42
  • can't stress the @sourcejedi's comment enough. – João Rebelo Mar 02 '17 at 12:23
  • What is the proper solution for transactional file operations? – Amirhosein Al Mar 04 '21 at 15:22
9

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

The transactional file package provides you with code that allows you to have atomic read and write operations on any file system. The file resource manager offers you the possibility to isolate a number of operations on a set of files in a transaction. Using the locks package it is able to offer you full ACID transactions including serializability. Of course to make this work all access to the managed files must be done by this manager. Direct access to the file system can not be monitored by the manager.

update

Be aware that the status on the front page says:

We have decided to move the project to dormant as we are convinced that the main advertised feature transactional file access can not be implemented reliably. We are convinced that no such implementation can be possible on top of an ordinary file system. Although there are other useful parts (as multi level locking including deadlock detection) the transactional file system is the main reason people use this library for. As it simply can not be made fully transactional, it does not work as advertised.

bernie
  • 9,820
  • 5
  • 62
  • 92
pjp
  • 17,039
  • 6
  • 33
  • 58
5

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.

bernie
  • 9,820
  • 5
  • 62
  • 92
nitin
  • 119
  • 2
  • 1
4

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
  • 81,358
  • 34
  • 189
  • 227
  • It seems a quite straight forward solution. I like KISS options so I'll try it. – Giroscopio Aug 21 '09 at 10:14
  • This doesn't handle the situation where something goes wrong with the file write. In that case simply renaming it will persist the now potentially corrupted file – L. Blanc Oct 25 '16 at 13:55
4

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).

Adamski
  • 54,009
  • 15
  • 113
  • 152
3

JBossTS proposes its own implementation for transactional file i/o, as part of the Narayana project (formerly called JBossTS).

sleske
  • 81,358
  • 34
  • 189
  • 227
Yves Martin
  • 10,217
  • 2
  • 38
  • 77