データベースシステムでは、データの一貫性と完全性を確保するため、複数プロセスによる同時書き込みを防止する機構が必要です。協調型ロックプロトコルでは、プロセス間で相互に協調し、特定の規則に従ってロック取得を決定します。
書き込み操作を行うプロセスは、事前にロックを要求する必要があります。ロックが利用可能な場合、プロセスはロックを取得し操作を実行します。操作完了後、プロセスはロックを解放し、他のプロセスが利用できるようにします。
協調型ロックプロトコルの実装例
import java.nio.file.*;
import java.nio.channels.*;
public class FileLockHandler {
private final Path lockPath;
private FileChannel channel;
private FileLock activeLock;
public FileLockHandler(String fileName) throws IOException {
this.lockPath = Paths.get(fileName);
this.channel = FileChannel.open(lockPath,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE);
}
public boolean acquireLock() throws IOException {
activeLock = channel.tryLock();
return activeLock != null;
}
public void releaseLock() {
if (activeLock != null) {
try {
activeLock.release();
} catch (IOException ex) {
// 例外処理
}
}
try {
channel.close();
} catch (IOException ex) {
// 例外処理
}
}
public static void executeWithLock() {
FileLockHandler handler = new FileLockHandler("db.lock");
try {
if (handler.acquireLock()) {
// データベース操作実行
} else {
System.out.println("ロック取得失敗: 他プロセスが使用中");
}
} finally {
handler.releaseLock();
}
}
}
ポートベースロック機構の実装
import java.net.*;
public class PortBasedLock {
private ServerSocket lockSocket;
public PortBasedLock(int portNum) throws IOException {
this.lockSocket = new ServerSocket(portNum);
}
public boolean attemptLock() {
try {
lockSocket.bind(new InetSocketAddress("127.0.0.1", lockSocket.getLocalPort()));
return true;
} catch (BindException e) {
return false;
}
}
public void release() {
try {
lockSocket.close();
} catch (IOException ex) {
// 例外処理
}
}
public static void main(String[] args) {
PortBasedLock locker = null;
try {
locker = new PortBasedLock(54321);
if (locker.attemptLock()) {
// データベース処理実行
}
} catch (IOException e) {
// 例外処理
} finally {
if (locker != null) locker.release();
}
}
}