LOCK IN SHARE MODE umožní 2. vláknu číst hodnotu, ale skutečná hodnota bude ta před dotazem (přečtení potvrzeno) nebo před zahájením transakce (opakovatelné čtení) (protože MySQL používá více verzí; a jaká musí být vidět druhou transakcí je definována úrovní izolace). Pokud tedy 1. transakce není v době čtení potvrzena, bude načtena stará hodnota.
Ve vašem scénáři je nejlepší mít 1 transakci, která uzamkne záznam s výběrem pro aktualizaci, jiná než funguje na záznamu a při potvrzení/rollbacku třetí odemkne záznam.
Transakce druhého vlákna s výběrem pro aktualizaci počká na dokončení první, pak přečte skutečnou hodnotu a rozhodne se nepokračovat v dalších transakcích, ale informovat uživatele, že záznam je uzamčen.
Abyste předešli uváznutí, ujistěte se, že provádíte select for update
pomocí jedinečného indexu.
Příklad kódu:
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);