LOCK IN SHARE MODE vil tillade den 2. tråd at læse værdien, men den faktiske værdi vil være den før forespørgslen (læs commited) eller før transaktionen (gentagelig læsning) er startet (da MySQL bruger multi-versioning; og hvad skal ses af den anden transaktion er defineret af isolationsniveauet). Så hvis den 1. transaktion ikke er begået på tidspunktet for aflæsningen, vil den gamle værdi blive læst.
I dit scenarie er det bedst at have 1 transaktion, der låser posten med vælg til opdatering, en anden end fungerer på posten og ved commit/rollback låser den tredje op for posten.
Den anden trådtransaktion med vælg til opdatering vil vente på, at den første er fuldført, vil derefter læse den faktiske værdi og beslutte ikke at fortsætte med de andre transaktioner, men informere brugeren om, at posten er låst.
For at undgå dødvande skal du sørge for at select for update
ved hjælp af et unikt indeks.
Eksempelkode:
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);