java - Nilocker 无法在 Spring Boot 应用程序中工作

标签 java spring locking spring-integration nio

尝试通过启动指向包含 10 个文件的同一源路径的同一应用程序的两个实例来测试 Spring Boot 应用程序中的文件锁定机制。预计只有一个实例应该处理一个文件,一旦处理完毕,它将从源中删除。相同的文件不应被其他实例处理。因此将 Niolocker 添加到扫描仪中。在 Windows 和 Linux 环境中进行了测试。但是在 Windows 中,两个实例都面临以下异常...在 Linux 中,两个实例轮询/处理同一个文件。在 Linux 中没有影响。已实现以下逻辑来获取锁。

请就此提出建议。

Windows 异常(exception):

java.io.IOException:进程无法访问该文件,因为另一个进程已锁定文件的一部分

Linux: 两个实例轮询器都会选择相同的文件并对其进行处理

<file:inbound-channel-adapter id="filesInChannel" directory="file:${base.path}" auto-startup="false" scanner="recursiveScanner" auto-create-directory="true">
  <integration:poller id="poller" max-messages-per-poll="${max.messages.per.poll}" fixed-rate="${message.read.frequency}" task-executor="pollingExecutor">
    <integration:transactional transaction-manager="transactionManager" />
  </integration:poller>
  </file:inbound-channel-adapter>


<bean id="inboundFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
     <constructor-arg>
         <list>
            <bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter"/>
            <bean class="org.springframework.integration.file.filters.RegexPatternFileListFilter">
                <constructor-arg value="${file.type}"/>
           </bean>
         </list>
    </constructor-arg>
</bean>

<bean id="inboundChannelNioLocker" class="org.springframework.integration.file.locking.NioFileLocker" /> 

<bean id="recursiveScanner" class="org.springframework.integration.file.RecursiveDirectoryScanner">
        <property name="filter" ref="inboundFilter" />
        <property name="locker" ref="inboundChannelNioLocker"/>
</bean>

最佳答案

NioLocker 实际上依赖于操作系统,并且不保证对文件的独占访问。好吧,只有 Windows 才能正确地为我们做到这一点。

我什至开始考虑弃用它并将其从框架中完全删除。它给目标用户带来了太多的困惑......

您需要考虑使用基于共享ConcurrentMetadataStoreFileSystemPersistentAcceptOnceFileListFilter,而不是文件锁。因此,通过这种方式,实际上只有一个实例会拾取该文件进行处理。所有其他人将跳过它并继续处理下一个文件。

参见Reference Manual了解更多信息。

关于java - Nilocker 无法在 Spring Boot 应用程序中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51866918/

相关文章:

Spring /RabbitMQ : transaction management

MySQL - 如何锁定单行?

java - 如何在不同的应用程序级别锁定文件?

c++ - 与 std::mutex 相比,其他互斥包装器库有哪些优势?

java - 根据给定的前缀对字符串列表进行排序

java - 继续向类(class)提供信息

spring - docker 镜像正在运行,但无法访问 Spring Boot 应用程序中的其余端点

java - 在文件夹中创建 .asm 文件作为 JMenuItems 并将它们添加到 JMenu,添加 ActionListener 事件

java - Logback SMTPAppender 在特定时间只发送一封电子邮件,但有所有异常(exception)情况

java - Spring Data (Hibernate) 动态 WHERE 子句