How best to file lock in Java cluster

你。 提交于 2019-12-10 15:34:12

问题


I have a cluster of servers running on JBoss. I need to update a file in a safe manner. To be specific, I need to

  1. lock a file A -- blocking if it is already locked, in a safe manner so that if the JVM was to die suddenly there would no dangling locks. A 30 second timeout would be fine.
  2. read the file A
  3. change the contents
  4. write the file to a temp name A.tmp
  5. delete the original file A
  6. rename the A.tmp to the proper name A
  7. unlock the file A

When I look at java.nio.FileLock, it seems to be associated with an InputStream. I really just need to lock an abstract name. I don't need to lock a portion of a file. I could create a lock file for this (separate from the data file) if that is the best choice. However the main point of my problem is that I need to get the lock BEFORE I read, and then release the lock after I update the file. Note that I update the file in a manner to assure that I never have a partially written file on the file system. I need to write the whole file, and then rename it after it is written, to assure that whatever file holds that name has a complete set of contents, and if the process dies during writing it leaves behind a temp file which can easily be cleaned up later.

Is java.nio.FileLock really intended for this kind of use? Or should I be looking at something else?


回答1:


Here is what I ended up doing. For every file named "XXX", I use a zero length lock file named "XXX#LOCK"

  1. I lock this for update with an RandomAccessFile.

  2. While this lock file is locked, I manipulate the actual files in question: reading original file, streaming to a temp file, deleting the original, and renaming the temp file, etc.

  3. I unlock the lockfile

The code for locking:

    File lockFile = new File(target.getParent(), target.getName() + "#LOCK");
    lockAccessFile = new RandomAccessFile(lockFile, "rw");
    FileChannel lockChannel = lockAccessFile.getChannel();
    lock = lockChannel.lock();

code for unlocking:

    if (lock != null) {
        lock.release();
        lock = null;
    }
    if (lockAccessFile != null) {
        lockAccessFile.close();
        lockAccessFile = null;
    }

I wrap this together in a class that makes the locking and unlocking together with the reading or writing of the original file. As you can see, lock and lockAccessFile are member variables.

I never actually write anything to the lock file, but they exist in the folder. Since I have a small number of files to manage in this way (6 of them), I just leave the LOCK files in there as ugly, but harmless, overhead.

This works within my code across the multi-host cluster because my code is the only thing manipulating those files. The biggest problem is that if some other code started manipulating the files without knowing this convention, it would cause problems. i have not found any evidence that there is a standard way to handle this problem that would be enforced by the OS and at the same time supported by Java. If you know of any, let me know.



来源:https://stackoverflow.com/questions/38526966/how-best-to-file-lock-in-java-cluster

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!