0

SELECT...FOR UPDATEクエリを使用してテーブルをロックしています。残念ながら、次のように、同じテーブル内の 2 つの異なる行セットをロックする必要がある状況があります。

SELECT * FROM mytable WHERE attribute1 = 'something' FOR UPDATE
SELECT * FROM mytable WHERE attribute2 = 'somethingelse' FOR UPDATE
UPDATE mytable SET  attribute2 = 'somethingnew' WHERE somethingelse

両方の行セットをロックする必要があります。私がやっていることは、テーブル内のオブジェクトが特定の状態にないことを確認してから、その状態にすることができる他のオブジェクトを見つけてそこに置くことです。目標は、mysql にエンコードするには複雑すぎる特定の制約を満たすことです。

では...問題は、SELECT...FOR UPDATE同じトランザクション内で同じテーブルから 2 回アクセスするとどうなるかということです。最初のロックは解除されますか? これが事実であるという証拠を見てきましたが、確認する方法がよくわかりません。

4

2 に答える 2

1

ロックは、コミットまたはロールバック時にのみ解放されます。一方、単一のトランザクションがそれ自体でブロックされることはありません。したがって、1 つのスレッドだけがそれを実行している限り、上記は問題ないはずです。

複数のスレッドが上記を実行している場合、デッドロックする恐れがあります。それが必要な場合は、たとえば上記の Jaydee の回答のように、両方のセットを一度にロックする単一の SQL ステートメントが必要になります。

于 2011-12-07T06:31:29.023 に答える
0

のようなものはどうですか

SELECT * FROM mytable WHERE attribute1 = 'something' 
    or attribute2 = 'somethingelse' FOR UPDATE

UPDATE mytable SET  attribute2 = 'somethingnew' WHERE somethingelse

あなたの質問に対する直接の答えはわかりませんが、MySQL のマニュアルには、トランザクションが完了したとき (コミットまたはロールバック) にロックが解放されると書かれています。あなたの場合、実際には2つの選択は必要ありません。

于 2010-12-15T15:00:16.757 に答える