2014-04-28 86 views
0

从文件读取行并处理它们时,我在某些代码中使用文件系统锁。这是因为我的架构有多个应用程序服务器;我只想要一台服务器来处理每一行以避免数据重复。Java中的文件系统锁

我在辅助方法中创建DTO。该对象将填充锁定详细信息,该信息可以由帮助器方法返回,随后可以查询该锁定是否成功。如果是这样,文件中的行可以被处理。

通常,如果两台服务器同时尝试处理文件中的行,则其中一个服务器会抛出异常,因为该文件已被另一台服务器锁定。如果发生这种情况,我的代码会捕获异常并移至文件的下一行。

锁定如下实施:

String filename = <Unique identifier of record being processed>; 
File lockfile = new File(System.getProperty("java.io.tmpdir"), filename); 
RandomAccessFile randomAccessfile = new RandomAccessFile(lockfile, "rw"); 
FileChannel fileChannel = randomAccessfile.getChannel(); 

FileLockDTO fileLockDTO = new FileLockDTO(); 
fileLockDTO.setLockedfile(lockfile); 
fileLockDTO.setRandomAccessfile(randomAccessfile); 
fileLockDTO.setFileLock(fileChannel.tryLock()); 

对于绝大多数的时间,代码效果很好。但在极少数情况下,出现重复记录,这表明存在一个边缘情况,即多个应用程序服务器可以在同一时间看似创建一个锁。

我看了很长的&努力在代码和尝试了大量的测试,但不能确定如何发生。只是想知道有没有人有任何想法?

在此先感谢您的帮助。

+0

我正在使用Java版本1.7。 – GarlicBread

+0

然后你想尝试'Files.createFile(pathHere)'。 – fge

+2

决斗应用程序服务器从文件读取行似乎不可能成功。你需要一个真正的排队系统;你可以使用AMQ,ZMQ或MongoDB,或者... – bmargulies

回答

-1

FileLock的javadocs:锁定

实际上是否阻止另一个程序访问该锁定区域的内容是与系统相关的和因此是未指定。某些系统的本地文件锁定功能仅仅是建议性的,这意味着程序必须协作观察已知的锁定协议以保证数据的完整性。

而且从FileChannel.tryLock() javadocs:(重点是我的)一个OverlappingFileLockException抛出

如果所请求区域重叠的锁已经被此Java虚拟机举行,或者如果另一个线程已被此方法阻止并试图锁定重叠区域

这是一个简单的故障情景乌尔应用程式:

  1. 服务器A的查询,以查看是否在资源是否存在一个锁1 =>返回false
  2. 服务器B的查询,以查看是否在资源是否存在一个锁1 =>返回false
  3. 服务器A上运行在您的代码片段中的第1-4行成功
  4. 服务器B在上面的代码片段中运行第1-4行并成功(会阻止它吗?)
  5. 服务器A创建DTO
  6. 服务器B创建的DTO(根据不同的操作系统,调用tryLock()可能不会停止任何东西)
  7. 服务器A处理“锁定”记录
  8. 服务器B处理“锁定”记录
-1

您必须依靠FileLockDTO.setFileLock()中的空检查或任何您拥有它的位置(如果确实有它)。这一切对我来说似乎都太精细了。我只是锁定你正在阅读的实际文件的实际行,而不是引入这些二级锁文件。然后,如果您遇到现有的锁,则知道跳过该行。或者使用一种只能传递一行的数据结构,并消除整个问题,例如某种类型的MQ或数据库。

编辑下载者和/或FileLocks无法跨越JVM或进程工作的理论的拥护者需要阅读文档。

+1

@Asaph不幸的是,Javadoc并不同意你的看法:“这个文件锁定API旨在直接映射到底层操作系统的本地锁定设施。因此,所有保存在文件中的程序访问文件,而不管这些程序的编写语言。“ – EJP

+0

我正在阅读文档并引用并链接到它们。 “抛出OverlappingFileLockException”如果与此请求的区域重叠的锁已被此Java虚拟机占用,或者此方法中的另一个线程已被阻止,并且正试图锁定同一文件的重叠区域,则返回“ - http ://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#lock() – Asaph

+1

@Asaph以任何方式都不支持您的争用。它也与我引用的部分相矛盾。你抓着吸管。 – EJP

相关问题