2009-02-07 11 views
2

간단히 말해서 : 백엔드로 sqlitejdbc를 사용하는 스윙 응용 프로그램입니다. 현재 동일한 데이터베이스 파일로 작업하는 다중 인스턴스를 실행해도 아무런 문제가 없습니다. 그리고 있어야합니다. 파일이 잠겨 있으므로 (앱이 실행되는 동안 파일을 삭제할 수 없음) 검사가 간단해야합니다. 밝혀지지 않았다.FileChannel 및 RandomAccessFile이 작동하지 않는 것 같습니다.

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

에서

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()); 

결과 응용 프로그램이 실행 여부에 상관없이. 요점을 놓치고 있습니까? TIA.

+0

어떤 OS입니까? 내가 이해 하듯이 실제 잠금 메커니즘은 OS에 따라 다릅니다. –

답변

2

FileLock은 개별 스레드가 아닌 JVM 전용입니다. 따라서 Swing 앱과 동일한 프로세스 내에서 코드를 실행하면 JVM에서 공유하기 때문에 잠금을 얻게됩니다.

스윙 앱이 실행 중이 아니면 다른 프로세스가 잠금을 위해 경합하지 않으므로 제대로 작동 할 것입니다.

+0

설명해 주셔서 감사합니다. fs 레벨 잠금을 확인하는 방법을 알고 있습니까? – yanchenko

+0

아닙니다. 크로스 플랫폼 (및 크로스 프로세스) 파일 시스템 잠금은 실제로 프로세스 간의 조정을 통해서만 수행됩니다. 하나의 프로세스에서 모든 파일 액세스가 발생합니까? 그렇다면, 해당 파일에 대한 작업을 하나의 클래스로 추상화해야합니다. 그렇지 않다면 터치/잠금 파일을 시도 할 수 있습니다. – Kevin

+1

아니요, 다른 Java VM간에 액세스가 공유됩니다. – yanchenko

2

파일 시스템 수준 잠금은 다른 응용 프로그램과 상호 작용합니다. 이 중 하나를 FileChannel에서 가져옵니다. 따라서 예제 코드에서 수행하는 작업은 파일을 다른 프로세스 (예 : vi)에 잠긴 것처럼 보입니다.

그러나 JVM 내의 다른 Java 스레드 또는 프로세스는 잠금을 볼 수 없습니다. 핵심 문장은 입니다. "파일 잠금은 전체 Java 가상 머신을 대신하여 수행되며 동일한 가상 시스템 내의 여러 스레드가 파일에 액세스하는 것을 제어하는 ​​데 적합하지 않습니다." 잠금이 표시되지 않으므로 응용 프로그램과 동일한 JVM에서 sqlitejdbc를 실행하고 있습니다.

그럼 자물쇠를 가져 오는 코드를 제어하지 않는다고 가정하면 JVM이 이미 파일에 대한 잠금을 획득했는지 어떻게 알 수 있습니까? 이 코드로 예를 들어, 시도하고 파일의 다른 부분 집합에 배타적 잠금을 획득되는 것 한 가지 제안 : 당신이은 OverlappingFileLockException를 받아야 잠금이 이미있는 경우

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

. 이것은 다소 해킹되지만 일할 수도 있습니다.

+0

그러나 말하자면, 실행 가능한 jar 파일을 두 개 실행하면 각 실행 파일은 Java VM의 자체 복사본으로 실행됩니다. – yanchenko

0

실험을 조금 할 수 있습니까? 이 프로그램 (수면 그냥 코드)의 두 복사본을 실행

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/드라이브/JVM에서 작동하지 않는 것을 알고 고정하지 않습니다. 이것이 잠기면 논리에 잘못된 것이 있습니다. 의견을 통해 그 결과를 알려주십시오.

+0

첫 번째 스레드가 잠금을 가져오고 isOpen()에 대한 모든 후속 보고서가 'true'로 표시되고 tryLock()에서 OverlappingFileLockException으로 실패합니다. – yanchenko