Domanda

Per dirla semplice: un'applicazione swing che utilizza sqlitejdbc come backend. Attualmente, non c'è nessun problema di lanciare più istanze che lavorano con lo stesso file di database. E ci dovrebbe essere. Il file è bloccato (non in grado di eliminarlo mentre l'applicazione è in esecuzione) in modo che il controllo dovrebbe essere banale. Si scopre che non.

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

risultati in

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

Non importa se l'applicazione è in esecuzione o meno. Mi sto perdendo il punto? TIA.

È stato utile?

Soluzione

FileLocks sono esclusivi a JVM, non un singolo filo. Quindi, se è stato eseguito il codice all'interno dello stesso processo come il vostro swing app, si otterrebbe il blocco perché è condiviso dalla JVM.

Se il vostro swing applicazione non è in esecuzione, nessun altro processo si contendono il blocco in modo da ottenere che non v'è bene.

Altri suggerimenti

un blocco di file a livello di sistema interagisce con altre applicazioni. È possibile ottenere uno di questi da FileChannel. Quindi, ciò che si fa nel codice di esempio renderà il file sembra bloccato a un altro processo, ad esempio vi.

Tuttavia, altri thread Java o processi all'interno della JVM non vedrà la serratura. La frase chiave è "blocchi dei file sono detenuti per conto di tutta la macchina virtuale Java. Essi non sono adatti per controllare l'accesso a un file da più thread all'interno della stessa macchina virtuale." non si è vedendo il bloccare, quindi si esegue sqlitejdbc all'interno della stessa JVM come applicazione.

Quindi la domanda è come si fa a vedere se il vostro JVM ha già acquisito un blocco su un file (supponendo che non controlli il codice di acquisire il blocco)? Un suggerimento che avrei è cercare di acquisire un blocco esclusivo su un diverso sottoinsieme di file, ad esempio con questo codice:

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

Se c'è già un blocco si dovrebbe ottenere un OverlappingFileLockException. Questo è un po 'hacky, ma potrebbe funzionare.

Si può fare un piccolo esperimento? Eseguire due copie di questo programma (basta il codice con un sonno):

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

Se questo non si blocca a sapere che tryLock () non funziona sul vostro OS / unità / JVM. Se questo non bloccare poi qualcosa è sbagliato con la vostra logica. Fateci sapere il risultato in un commento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top