LOCK IN SHARE MODE permitirá que o 2º thread leia o valor, mas o valor real será aquele antes da consulta (leitura confirmada) ou antes da transação (leitura repetitiva) ser iniciada (já que o MySQL usa multi-versão; e o que tem que ser visto pela segunda transação é definido pelo nível de isolamento). Portanto, se a 1ª transação não for confirmada no momento da leitura, o valor antigo será lido.
No seu cenário é melhor ter 1 transação que bloqueie o registro com select for update, outra que funcione no registro e no commit/rollback a terceira desbloqueie o registro.
A segunda transação de thread com seleção para atualização aguardará a conclusão da primeira, lerá o valor real e decidirá não continuar com as outras transações, mas informará ao usuário que o registro está bloqueado.
Para evitar impasse, certifique-se de estar fazendo a
select for update
usando um índice exclusivo. Código de exemplo:
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);