如何确定是否存在H2数据库文件锁?

时间:2014-11-05 22:56:35

标签: java database h2 filelock

由于我不会解释的原因(因为人们将在另一个主题上引导他们的回答,而不是我手头的问题),我需要知道如何确定我的H2数据库是否被锁定。使用Java代码,如何确定我的数据库中是否存在锁定文件?

1 个答案:

答案 0 :(得分:5)

对于阅读此问题的其他人,我需要解释为什么您不应该自己做,并让数据库检测自己是否被锁定。首先,数据库文件锁定是一种实现细节,可以在将来的数据库版本中进行更改。然后,存在竞争条件:如果您看到锁定现在不存在,则可能在一秒之后存在。所以唯一可靠的方法是尝试锁定。所以:尝试以读写模式打开数据库。缺点:它有点慢,因为它将初始化数据库并在需要时运行恢复代码。我明白这不是你想要的,因为它很慢(对吧?)。

对于较低级别的方法,它取决于您使用的H2版本。

版本1.4(目前为测试版)

尝试使用以下代码锁定文件:

static boolean isLocked(String fileName) {
    try {
        RandomAccessFile f = new RandomAccessFile(fileName, "r");
        try {
            FileLock lock = f.getChannel().tryLock(0, Long.MAX_VALUE, true);
            if (lock != null) {
                lock.release();
                return false;
            }
        } finally {
            f.close();
        }
    } catch (IOException e) {
        // ignore
    }
    return true;
}

或使用H2代码(来自MVStore):

static boolean isLocked(String fileName) {
    FileStore fs = new FileStore();
    try {
        fs.open(fileName, true, null);
        return false;
    } catch (IllegalStateException e) {
        return true;
    } finally {
        fs.close();
    }
}

版本1.3(稳定)和1.4,MVStore已禁用

仅检查文件<databaseName>.lock.db是否存在是不够的。如果进程被终止,即使数据库未打开也可能存在。所以一些示例代码(未经测试)是:

// file name must be:
// path + databaseName + Constants.SUFFIX_LOCK_FILE
static boolean isLocked(String fileName) {
    try {
        FileLock lock = new FileLock(new TraceSystem(null), fileName, 1000);
        lock.lock(FileLock.LOCK_FILE);
        lock.unlock();
        return false;
    } catch (Exception e) {
        return true;
    }
}