Biasanya, solusi untuk masalah konkurensi tersebut melibatkan transaksi dan penguncian yang optimis :saat Anda memperbarui penghitung, tambahkan where
klausa untuk memeriksa nilai lama dan menghitung jumlah baris yang diperbarui.
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
Jika penghitung telah diperbarui sementara itu, pembaruan tidak akan mengubah baris apa pun -- jadi Anda tahu bahwa Anda harus melakukan rollback dan mencoba transaksi sekali lagi.
Satu masalah adalah bahwa hal itu dapat menyebabkan pertikaian yang tinggi , dengan hanya sedikit transaksi yang berhasil dan banyak yang gagal.
Maka mungkin lebih baik untuk tetap menggunakan penguncian pesimis , tempat Anda mengunci baris terlebih dahulu, lalu memperbaruinya. Tetapi hanya tolok ukur yang akan memberi tahu Anda.
EDIT
Jika Anda menggunakan transaksi tanpa penguncian optimis, skenario berikut dapat terjadi.
Max authorized = 50. Current value = 49.
T1: start tx, read value --> 49
T2: start tx, read value --> 49
T1: update value --> 50, acquire a row lock
T1: commits --> release the lock
T2: update value --> 50, acquire a row lock
T2: commits --> release the lock
Kedua transaksi berhasil, nilainya 50, tetapi ada inkonsistensi.