Selamat datang di part 40 dari seri tutorial Pemrograman & Komputer! Kali ini, kita akan membahas manajemen konkurensi menggunakan Mutex (Mutual Exclusion) di PHP. Manajemen konkurensi penting untuk memastikan integritas data dalam aplikasi yang menangani banyak permintaan secara bersamaan. Part ini adalah kelanjutan dari tutorial sebelumnya tentang Circuit Breaker Pattern, karena kedua konsep ini penting dalam membangun sistem yang tangguh dan handal.
Prasyarat:
Konkurensi adalah kemampuan suatu sistem untuk menangani banyak tugas secara bersamaan. Dalam konteks web, ini berarti menangani banyak permintaan pengguna secara paralel. Namun, konkurensi dapat menyebabkan masalah seperti race conditions, di mana beberapa proses mencoba mengakses dan memodifikasi data yang sama secara bersamaan, mengakibatkan hasil yang tidak terduga.
Mutex adalah mekanisme sinkronisasi yang digunakan untuk melindungi sumber daya bersama dari akses bersamaan. Bayangkan sebuah ruangan yang hanya bisa dimasuki satu orang pada satu waktu. Kunci ruangan tersebut adalah mutex. Sebelum masuk, seseorang harus mendapatkan kunci (acquire mutex). Setelah selesai, orang tersebut harus mengembalikan kunci (release mutex) agar orang lain bisa masuk.
Mari kita buat contoh sederhana bagaimana menggunakan mutex di PHP. PHP tidak memiliki dukungan mutex bawaan, tetapi kita dapat menggunakan ekstensi seperti php-pthread (membutuhkan instalasi dan konfigurasi) atau solusi berbasis file.
Contoh berikut menggunakan solusi berbasis file untuk mensimulasikan mutex:
<?php
class Mutex {
private $lockFile;
private $lockFilePath;
public function __construct(string $name) {
$this->lockFile = $name . '.lock';
$this->lockFilePath = sys_get_temp_dir() . '/' . $this->lockFile;
}
public function acquire(int $timeout = 0): bool {
$start = time();
while (file_exists($this->lockFilePath)) {
if ($timeout > 0 && (time() - $start) >= $timeout) {
return false; // Timeout
}
usleep(1000); // Sleep for 1ms to avoid busy-waiting
}
touch($this->lockFilePath);
return true;
}
public function release(): bool {
if (file_exists($this->lockFilePath)) {
return unlink($this->lockFilePath);
}
return false;
}
}
// Contoh penggunaan
$mutex = new Mutex('my_resource');
if ($mutex->acquire(5)) { // Mencoba mendapatkan kunci dengan timeout 5 detik
echo "Kunci berhasil didapatkan.\n";
// Lakukan operasi kritis di sini
sleep(2); // Mensimulasikan operasi yang memakan waktu
echo "Selesai melakukan operasi kritis.\n";
$mutex->release(); // Melepas kunci
echo "Kunci berhasil dilepas.\n";
} else {
echo "Gagal mendapatkan kunci setelah timeout.\n";
}
?>
Penjelasan Kode:
Mutex class: Mensimulasikan mutex menggunakan file lock.__construct: Inisialisasi nama file lock.acquire: Mencoba mendapatkan kunci. Jika file lock sudah ada, menunggu hingga timeout atau file dihapus.release: Menghapus file lock, melepaskan kunci.Mutex, mencoba mendapatkan kunci, melakukan operasi kritis, dan melepaskan kunci.Modifikasi kode di atas untuk menambahkan logging. Setiap kali mutex di-acquire atau di-release, tulis pesan ke file log. Ini akan membantu Anda memantau penggunaan mutex dan mendeteksi potensi masalah.