문제

간단하게 말하자면:sqlitejdbc를 백엔드로 사용하는 스윙 앱.현재 동일한 데이터베이스 파일로 작동하는 여러 인스턴스를 시작하는 데 문제가 없습니다.그리고 있어야합니다.파일이 잠겨 있으므로(앱이 실행되는 동안 삭제할 수 없음) 검사가 간단해야 합니다.그렇지 않은 것으로 밝혀졌습니다.

    File f = new File("/path/to/file/db.sqlite");
    FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
    System.out.println(channel.isOpen());
    System.out.println(channel.tryLock());

결과

    true
    sun.nio.ch.FileLockImpl[0:9223372036854775807 exclusive valid]

앱이 실행 중인지 여부는 중요하지 않습니다.내가 요점을 놓치고 있는 걸까?티아.

도움이 되었습니까?

해결책

Filelocks는 개별 스레드가 아니라 JVM에만 해당됩니다. 따라서 스윙 앱과 동일한 프로세스 내에서 해당 코드를 실행하면 JVM이 공유하기 때문에 잠금 장치를 얻게됩니다.

스윙 앱이 실행되지 않으면 잠금 장치에 대한 다른 프로세스가 없으므로 잘 얻을 수 있습니다.

다른 팁

파일 시스템 수준 잠금은 다른 애플리케이션과 상호 작용합니다.FileChannel에서 이들 중 하나를 얻습니다.따라서 예제 코드에서 수행하는 작업은 파일이 vi와 같은 다른 프로세스에 잠겨 있는 것처럼 보이게 만듭니다.

그러나 JVM 내의 다른 Java 스레드 또는 프로세스에는 잠금이 표시되지 않습니다.핵심 문장은 "파일 잠금은 전체 Java 가상 머신을 대신하여 유지됩니다.동일한 가상 머신 내의 여러 스레드가 파일에 대한 액세스를 제어하는 ​​데 적합하지 않습니다." 잠금이 표시되지 않으므로 애플리케이션과 동일한 JVM 내에서 sqlitejdbc를 실행하고 있습니다.

따라서 질문은 JVM이 이미 파일에 대한 잠금을 획득했는지 여부를 어떻게 확인하는 것입니다(잠금을 획득하는 코드를 제어하지 않는다고 가정).제가 갖고 싶은 한 가지 제안은 예를 들어 다음 코드를 사용하여 파일의 다른 하위 집합에 대한 배타적 잠금을 획득하는 것입니다.

fc.tryLock(0L, 1L, false)

이미 잠금이 있는 경우 OverlappingFileLockException이 발생합니다.이것은 약간 해킹적이지만 작동할 수 있습니다.

약간의 실험을 할 수 있습니까? 이 프로그램의 두 부를 실행하십시오 (수면과 함께 코드 만) :

public class Main {
    public static void main(String [] args) throws Exception {
        File f = new File("/path/to/file/db.sqlite");
        FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
        System.out.println(channel.isOpen());
        System.out.println(channel.tryLock());
        Thread.sleep(60000);
    }
}

이것이 잠기지 않으면 trylock ()가 OS/Drive/JVM에서 작동하지 않는다는 것을 알 수 있습니다. 이것이 잠겨 있으면 다른 것이 당신의 논리에 잘못되었습니다. 의견이있는 결과를 알려주십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top