Programer
web pemula kadang-kadang tidak menyadari bahwa program/skrip yang dibuatnya
tidaklah seperti program desktop yang dijalankan oleh satu user. Melainkan,
dalam satu waktu bisa saja ada 10 atau 100 user yang “menembak” skrip Anda di
Web. Karena itu, isu locking dan konkurensi penting sekali. Contohnya adalah
seperti ini:
$res = mysql_query("SELECT value FROM counters WHERE name='counter1'"); list ($value) = mysql_fetch_row($res); $value++; // do something else first... $res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
Di
antara baris pertama (saat kita mengambil nilai record) dan baris keempat (saat
kita menaruh kembali nilai dalam record) mungkin saja telah terjadi beberapa
kali perubahan terhadap si record. Misalnya, pada baris pertama klien1
memperoleh nilai $value = 100. Di baris 3 $value
di-increment menjadi 101. Tapi apa yang terjadi jika selama selang waktu itu
nilai record counter1 telah menjadi 103 (karena misalnya klien2, klien3, dan
klien4 telah meng-incrementnya)? Oleh si klien1, counter1 direset kembali
menjadi 101 dan akibatnya increment oleh klien2, klien3, dan klien4 hilang.
Seharusnya nilai counter1 menjadi 104.
Untuk
kasus di atas, pemecahannya cukup gampang. Lakukan increment secara atomik:
// tidak perlu ambil nilai counter dulu... // do something else first... $res = mysql_query("UPDATE counter SET value=value+1 WHERE name='counter1'");
Tapi
dalam kasus lain, kadang-kadang kita harus melakukan locking terhadap tabel atau record untuk menjamin bahwa selama kita
// do something else… klien2,
klien3, dan klien4 tidak bisa seenaknya menaikkan nilai counter:
mysql_query("LOCK TABLES cuonters"); $res = mysql_query("SELECT value FROM counters WHERE name='counter1'"); list ($value) = mysql_fetch_row($res); // do something else first... increase value or something... $res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'"); mysql_query("UNLOCK TABLES");
atau
(lebih baik karena kita tidak perlu melock keseluruhan tabel):
mysql_query("SELECT GET_LOCK('lock1')"); $res = mysql_query("SELECT value FROM counters WHERE name='counter1'"); list ($value) = mysql_fetch_row($res); // do something else first... increase value or something... $res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'"); mysql_query("SELECT RELEASE_LOCK('lock1')");
Ingat,
locking dapat berakibat samping yaitu deadlock.
Transaksi. Transaksi pun sesuatu yang
dipergunakan secara meluas di dunia database, tapi hampir tidak pernah kita
jumpai di bahasa pemrograman (ini karena data di bahasa pemrograman ditaruh
dalam variabel di memori semua; tidak ada isu disk yang
crash/lambat/rusak/harus disinkronkan dengan data di memori). Karena itu Anda
perlu memahami konsep ini dari buku-buku tentang database.
0 komentar:
Posting Komentar