Question

Pour faire simple: une application swing qui utilise sqlitejdbc comme back-end. À l'heure actuelle, il n'y a pas de problème de lancer plusieurs instances qui fonctionnent avec le même fichier de base de données. Et il devrait y avoir. Le fichier est verrouillé (ne peut pas le supprimer lorsque l'application est en cours d'exécution) de sorte que le chèque doit être trivial. Il s'avère pas.

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

résultats dans

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

Peu importe si l'application est en cours d'exécution ou non. Est-ce que je manque le point? TIA.

Était-ce utile?

La solution

FileLocks sont exclusifs à la machine virtuelle Java, pas un fil individuel. Donc, si vous exécutiez ce code dans le même processus que votre application Swing, vous obtiendrez la serrure parce qu'elle est partagée par la machine virtuelle Java.

Si votre application Swing ne fonctionne pas, aucun autre processus est disputant la serrure et vous obtiendrez là est bien.

Autres conseils

Un verrou de niveau du système de fichiers interagit avec d'autres applications. Vous obtenez l'un de ces de FileChannel. Alors ce que vous faites dans votre exemple de code va rendre le fichier semble verrouillé à un autre processus, par exemple vi.

Cependant, d'autres threads Java ou processus de la machine virtuelle Java ne verra pas le verrou. La phrase clé est « verrous de fichier sont détenus au nom de la machine virtuelle complète Java. Ils ne sont pas adaptés pour contrôler l'accès à un fichier par plusieurs threads dans la même machine virtuelle. » Vous ne voyez pas le verrouiller, de sorte que vous exécutez sqlitejdbc à partir de la même machine virtuelle Java que votre application.

La question est de savoir comment vous voyez si votre machine virtuelle Java a déjà acquis un verrou sur un fichier (en supposant que vous ne contrôlez pas le code acquisition de la serrure)? Une suggestion que je devrais essayer est un verrou exclusif sur un autre sous-ensemble du fichier, par exemple avec ce code:

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

S'il y a déjà un verrou, vous devriez obtenir un OverlappingFileLockException. C'est un peu aki mais pourrait fonctionner.

Pouvez-vous faire une petite expérience? Exécuter deux copies de ce programme (seulement votre code avec un sommeil):

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

Si cela ne vous savez pas verrouiller trylock () ne fonctionne pas sur votre système d'exploitation / disque / machine virtuelle Java. Si cela ne se verrouille alors quelque chose d'autre ne va pas avec votre logique. Faites-nous savoir le résultat dans un commentaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top