sql >> データベース >  >> RDS >> Mysql

更新v/s共有モードでのロックの場合:同時スレッドがロックされた行の更新された状態値を読み取れるようにします

    LOCK IN SHARE MODEを使用すると、2番目のスレッドが値を読み取ることができますが、実際の値は、クエリ(読み取りコミット)またはトランザクション(繰り返し可能読み取り)が開始される前(MySQLがマルチバージョニングを使用するため)の値になります。 2番目のトランザクションで確認する必要があります)は、分離レベルによって定義されます。したがって、読み取り時に最初のトランザクションがコミットされていない場合、古い値が読み取られます。

    シナリオでは、更新のためにselectを使用してレコードをロックするトランザクションを1つ持つのが最適です。これは、レコードで機能し、コミット/ロールバック時に3番目のトランザクションでレコードのロックを解除するものです。

    select for updateを使用した2番目のスレッドトランザクションは、最初のスレッドが完了するのを待ってから、実際の値を読み取り、他のトランザクションを続行しないことを決定しますが、レコードがロックされていることをユーザーに通知します。

    デッドロックを回避するには、select for updateを実行していることを確認してください 一意のインデックスを使用します。

    コード例:

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



    1. ユーロ記号がサイトに表示されない

    2. MySQL:SELECTはMAX_JOIN_SIZEを超える行を調べます

    3. PostgreSQLで行が更新されたときにタイムスタンプを更新する

    4. SQL Serverのデフォルトの日付タイムスタンプ?