Frage

Um es einfach: ein Schaukel-App, die sqlitejdbc als Backend verwendet. Derzeit gibt es kein Problem, mehrere Instanzen starten, die mit der gleichen Datenbankdatei arbeiten. Und sollte es sein. Die Datei ist gesperrt (es kann nicht gelöscht werden, während die App läuft), so sollte die Prüfung trivial sein. Es stellte sich heraus nicht.

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

Ergebnisse in

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

Egal, ob der App läuft oder nicht. Fehle ich den Punkt? TIA.

War es hilfreich?

Lösung

FileLocks sind exklusiv für die JVM, nicht einen einzelnen Thread. Also, wenn Sie diesen Code in dem gleichen Prozess wie Ihr Swing-App laufen, würden Sie das Schloss bekommen, weil es von der JVM gemeinsam genutzt wird.

Wenn Sie Ihr Swing-App nicht läuft, kein anderes Verfahren zur Sperre streit so werden erhalten Sie es dort gut ist.

Andere Tipps

Ein Dateisystemebene Sperre interagiert mit anderen Anwendungen. Sie erhalten eine davon aus Filechannel. Also, was Sie in Ihrem Beispielcode tun die Datei scheint zu einem anderen Prozess gesperrt, zum Beispiel vi.

Aber auch andere Java-Threads oder Prozesse innerhalb der JVM wird das Schloss nicht sehen. Der Schlüsselsatz ist „Dateisperren im Namen der gesamten virtuellen Java-Maschine gehalten werden. Sie eignen sich nicht für innerhalb derselben virtuellen Maschine von mehreren Threads Zugriff auf eine Datei zu steuern.“ Sie sehen nicht die zu sperren, so dass Sie sqlitejdbc innerhalb derselben JVM wie Ihre Anwendung ausgeführt wird.

Die Frage ist, wie Sie sehen, ob Ihre JVM erworben hat bereits eine Sperre für eine Datei (vorausgesetzt, Sie die Sperre den Code nicht steuern Acquiring)? Ein Vorschlag, den ich hätte, ist zu versuchen und erwerben eine exklusive Sperre auf einer anderen Teilmenge der Datei, zum Beispiel mit diesem Code:

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

Wenn bereits eine Sperre Sie ein OverlappingFileLockException bekommen sollten. Das ist ein bisschen hacky aber funktionieren könnte.

Können Sie ein kleines Experiment tun? Führen Sie zwei Kopien dieses Programms (nur Ihren Code mit einem Schlaf):

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

Wenn diese Sie nicht sperren, dass TryLock () auf Ihrem OS / Antrieb / JVM nicht funktioniert. Wenn dies nicht sperrt dann noch etwas anderes ist falsch mit Ihrer Logik. Lassen Sie uns das Ergebnis in einem Kommentar wissen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top