Reputation: 1935
I have to perform 2 actions, one to save data in db, one to save bytes on filesystem, and I would like these 2 actions to be executed atomically. Basically, if action 1 fails, the whole process fails, and if action 2 fails, same thing and db action is rollbacked.
public void doAction() {
this.saveData();
this.saveFile();
}
How is it possible to perform ACID transaction which involves database and filesystem in Java ?
Upvotes: 0
Views: 1467
Reputation: 64628
ACID requires not only to be able to rollback changes when one of the operations fail, it also requires isolation from other transaction. As soon as you store data to a file, changes get visible to others. Either committing the database before or after is a violation of the ACID rules.
However, you may still find a solution for the actual problem you have to solve. E.g. by synchronizing file access with database data (store file names and whether data is ready, for instance).
Also consider storing the data in a blob instead of a file.
Another more complicated way is to lock access to the data by the file system, so when a transaction is writing, all others are blocked from reading and writing of the file and the corresponding database data at the same time. E.g. Use an empty lock file (original-filename.lock) that blocks others from reading / writing the data in that file. This only works if you have a 1-to-1 relation to database data and if you don't do any complex querying (you should not read the data while it is locked). And of course it only works if you have control over everything that accesses the file or the database. It may not be very efficient. You still need to implement a rollback mechanism for the file changes (usually copy-rename stuff).
There are a couple of other solutions or workarounds, depending on your specific system. This questions is probably "too broad".
Upvotes: 1
Reputation: 18408
In general this is just impossible.
File systems are not a transactional resource (unless you're consciously and deliberately on a journaled filesystem or so) and even if they were there would still be the requirement that they can engage in a 2PC transaction, together with the db transaction, under an "external" transaction controller (who can steer and control the two-phase-commit process that will be required). Your chances are slim.
You can try to do all sorts of thing yourself, e.g. keep a log of the pre-write state of any file (or file portions) written to, but basically you are then recreating a journaled file system yourself and unless you do so fully and completely (not an easy task), your system will still have (serious) holes in it.
Upvotes: 2