LÅS I DELNINGSLÄGE kommer att tillåta den andra tråden att läsa värdet, men det faktiska värdet kommer att vara det som föregår frågan (läs commited) eller innan transaktionen (repeterbar läsning) har startat (eftersom MySQL använder flera versioner; och vad måste ses av den andra transaktionen definieras av isoleringsnivån). Så om den första transaktionen inte genomförs vid tidpunkten för avläsningen kommer det gamla värdet att läsas.
I ditt scenario är det bäst att ha en transaktion som låser posten med välj för uppdatering, en annan än fungerar på posten och vid commit/rollback låser den tredje upp posten.
Den andra trådtransaktionen med välj för uppdatering väntar på att den första ska slutföras, läser sedan av det faktiska värdet och beslutar att inte fortsätta med de andra transaktionerna, utan informera användaren om att posten är låst.
För att undvika dödläge, se till att du gör select for update
med ett unikt index.
Exempelkod:
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);