LOCK IN SHARE MODE akan memungkinkan utas ke-2 untuk membaca nilainya, tetapi nilai sebenarnya adalah nilai sebelum kueri (baca berkomitmen) atau sebelum transaksi (pembacaan berulang) dimulai (karena MySQL menggunakan multi-versi; dan apa harus dilihat oleh transaksi kedua didefinisikan oleh tingkat isolasi). Jadi jika transaksi pertama tidak dilakukan pada saat membaca, nilai lama akan dibaca.
Dalam skenario Anda, yang terbaik adalah memiliki 1 transaksi yang mengunci catatan dengan pilih untuk pembaruan, selain yang berfungsi pada catatan dan saat komit/kembalikan yang ketiga membuka kunci catatan.
Transaksi utas kedua dengan pilih untuk pembaruan akan menunggu yang pertama selesai, kemudian akan membaca nilai aktual dan akan memutuskan untuk tidak melanjutkan dengan transaksi lain, tetapi untuk memberi tahu pengguna bahwa catatan dikunci.
Untuk menghindari kebuntuan, pastikan Anda melakukan select for update
menggunakan indeks unik.
Contoh kode:
connection.setautocommit(false);
//transaction-1
PreparedStatement ps1 = "Select locked from tableName for update where id="key" and locked=false);
ps1.executeQuery();
//transaction 2
PreparedStatement ps2 = "Update tableName set locked=true where id="key";
ps2.executeUpdate();
connection.setautocommit(true); // here we allow other transactions / threads to see the new value
connection.setautocommit(false);
//transaction 3
PreparedStatement ps3 = "Update tableName set aField="Sthg" where id="key" And date="D" and topic="T";
ps3.executeUpdate();
// probably more queries
// reset locked to false
PreparedStatement ps4 = "Update tableName set locked=false where id="key";
ps4.executeUpdate();
//commit
connection.setautocommit(true);