4

私はmysqlのドキュメントを読みましたが、すべてを理解していない可能性があります。私が探しているのは、他のセッションの読み取りからの行のロックです。行がロックされている間、他のセッションはロックが解除されるまで待機します。他のセッションにスナップショットから読み取らせたくありません!彼らはリリースが行われるまで待たなければなりません!

私が取得したいのは、次の例とまったく同じですが、テーブル全体のロックではなく単一の行の場合です。

START TRANSACTION
LOCK TABLES table1 WRITE
SELECT * FROM table1 WHERE id = 40912
UPDATE table1 SET column1 = 'value1' WHERE id = 40912
UNLOCK TABLES
COMMIT

前もって感謝します!

4

3 に答える 3

3

Elena Sharovar からの回答はそれを行う方法ですが、何が必要かを完全に説明していない可能性があります。SELECT を実行するすべてのプロセスは、同じ文字列で GET_LOCK を使用する必要があります。その場合、MySQL は自動的に (指定された秒数まで) 待機して、他のスレッドがロックを解放するまで結果を返します。

時間が上から下に進むと、次のようになります。

          THREAD 1                                 THREAD 2
DO GET_LOCK("table1.40912", 30)
SELECT * FROM table1 WHERE id=40912     DO GET_LOCK("table1.40912", 30)
[UPDATE query]                          [automatically waits]
[UPDATE query]                          [automatically waits]
DO RELEASE_LOCK("table1.40912")         [lock finally obtained, query terminates]
                                        SELECT * FROM table1 WHERE id=40912
于 2012-12-06T18:06:25.580 に答える
1

私はまだそれを試みていませんが、MySQL関数GET_LOCK(str、timeout)とRELEASE_LOCK(str)を使用することは可能です。ここで、「str」はロックを識別する任意の文字列です。

mysql_query('DO GET_LOCK("table1.40912", 60)')
mysql_query('SELECT * FROM table1 WHERE id = 40912')
mysql_query('UPDATE table1 SET column1 = 'value1' WHERE id = 40912')
mysql_query('DO RELEASE_LOCK("table1.40912")') 
于 2012-10-24T08:11:12.903 に答える
1

この興味深い問題(スナップショットが一貫している場合でも、MySQLにスナップショットを読み取らないようにする方法)について私が持っている最善のアイデアは、「SELECT FOR UPDATE#select-clause#」のように、「FORUPDATE」を使用してすべてを読み取ることです。 。

ただし、これらの選択が非常に狭いインデックスを使用してレコードを検索することは非常に重要です。つまり、読み取ったものをロックします。全表スキャンまたはUSINGWHERE(EXPLAINステートメント内)を介してSELECTをワイルドに実行すると、テーブルの広い領域のロック時間が長くなると、反応時間が長くなる可能性があります。

データベース抽象化レイヤーでテストすることをお勧めします。

このメカニズムのすべては、分離のドキュメントで読むことができます。

于 2012-10-24T08:24:01.207 に答える