سؤال

لوضعها بسيطة: التطبيق البديل الذي يستخدم 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]

وبغض النظر عن ما إذا كان التطبيق يعمل أم لا. أنا في عداد المفقودين النقطة؟ TIA.

هل كانت مفيدة؟

المحلول

وFileLocks تعود حصرا إلى JVM، وليس موضوع شخصي. حتى إذا قمت بتشغيل هذا الرمز داخل نفس العملية كتطبيق سوينغ الخاص بك، سوف تحصل على القفل ليتم مشاركتها من قبل JVM.

إذا التطبيق سوينغ الخاص بك لا يعمل، لا عملية أخرى معتبرا لقفل لذلك سوف تحصل عليه هناك شيء على ما يرام.

نصائح أخرى

ووتأمين مستوى نظام الملفات تتفاعل مع غيرها من التطبيقات. يمكنك الحصول على واحدة من هذه من FileChannel. ذلك ما تفعله في المثال التعليمات البرمجية الخاصة بك وسوف جعل الملف يبدو أن تغلق بابها لعملية أخرى، على سبيل المثال السادس.

ومع ذلك، فإن المواضيع جافا الأخرى أو العمليات داخل JVM أن يرى القفل. الجملة الأساسية هي <م> "تقام نيابة عن آلة جافا الافتراضية كاملة أقفال ملف. فهي ليست مناسبة للتحكم في الوصول إلى ملف المواضيع متعددة داخل نفس الجهاز الظاهري." أنت لا تبصر قفل، لذلك كنت تقوم بتشغيل sqlitejdbc من داخل نفس JVM كما طلبك.

وهكذا فإن السؤال هو كيف يمكنك معرفة ما إذا كان JVM الخاصة بك اكتسب بالفعل تأمين على ملف (على افتراض انك لا تتحكم رمز الحصول على تأمين)؟ اقتراح واحد كنت أود أن يكون هو محاولة الحصول على تأمين حصري على مجموعة فرعية مختلفة من الملف، على سبيل المثال مع هذا الرمز:

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

إذا كان هناك بالفعل القفل يجب عليك الحصول على OverlappingFileLockException. هذا هو hacky قليلا ولكن قد عمل.

ويمكنك أن تفعل القليل من التجربة؟ تشغيل نسختين من هذا البرنامج (فقط التعليمات البرمجية الخاصة بك مع النوم):

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 () لا يعمل على نظام التشغيل الخاص بك / حملة / JVM. إذا كان هذا لا قفل ثم شيء آخر هو الخطأ في المنطق الخاص. دعونا نعرف النتيجة في تعليق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top