Reputation: 531
For reasons that I will not explain (because people will direct their responses at the other topic, instead of my problem at hand), I need to know how to determine whether or not my H2 database is locked. Using Java code, how do I determine whether or not the lock file exists on my database?
Upvotes: 2
Views: 5323
Reputation: 50097
For others reading this question I need to explain why you you shouldn't do it yourself, and let the database detect itself whether it is locked or not. First of all, database file locking is an implementation detail that can and will change in future versions of the database. Then, there is a race condition: if you see the lock doesn't exist now, it may exist one second later. So the only reliable way is to try locking. So: try opening the database in read-write mode. Disadvantage: it is a bit slow, as it will initialize the database and also run the recovery code if needed. I understand this is not what you want, because it is slow (right?).
For lower level method, it depends which version of H2 you use.
Try locking the file itself using the following code:
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;
}
Or using H2 code (from the 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();
}
}
Simply checking if the file <databaseName>.lock.db
exists is not enough. It might exist even the database is not open, in case the process was killed. So some sample code (not tested) is:
// 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;
}
}
Upvotes: 5