Mysql
 sql >> Datenbank >  >> RDS >> Mysql

FOR UPDATE v/s LOCK IN SHARE MODE:Ermöglicht gleichzeitigen Threads das Lesen des aktualisierten Statuswerts der gesperrten Zeile

LOCK IN SHARE MODE wird es dem 2. Thread erlauben, den Wert zu lesen, aber der tatsächliche Wert wird derjenige sein, bevor die Abfrage (Lesen festgeschrieben) oder bevor die Transaktion (wiederholbares Lesen) gestartet wurde (da MySQL Multi-Versioning verwendet; und was von der zweiten Transaktion gesehen werden müssen, wird durch die Isolationsstufe definiert). Wenn also die 1. Transaktion zum Zeitpunkt des Lesens nicht festgeschrieben ist, wird der alte Wert gelesen.

In Ihrem Szenario ist es am besten, 1 Transaktion zu haben, die den Datensatz mit Select for Update sperrt, eine andere, die den Datensatz bearbeitet, und bei Commit/Rollback entsperrt eine dritte den Datensatz.

Die zweite Thread-Transaktion mit Select for Update wartet auf den Abschluss der ersten, liest dann den tatsächlichen Wert und entscheidet, nicht mit den anderen Transaktionen fortzufahren, sondern den Benutzer darüber zu informieren, dass der Datensatz gesperrt ist.

Stellen Sie sicher, dass Sie select for update ausführen, um Deadlocks zu vermeiden einen eindeutigen Index verwenden.

Beispielcode:

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);