2013-05-14 14 views
10

SQL標準では、マルチテーブルクエリのロック順序が指定されていますか?例えばマルチテーブルクエリのロック順序を決定する要因は何ですか?

は、所与:

SELECT department.id FROM permissions, terminals, departments WHERE department.id = ? AND terminal.id = ? AND permissions.parent = department.id AND permissions.child = terminals.id;

  1. をSQL標準がロック順序を保証しないか、(実装に固有)実行計画によって決定されますか?
  2. ロックオーダーを保証する方法はありますか?
  3. ロックの順序を保証する方法がない場合は、どのようにデッドロックを防止する必要がありますか?

UPDATE:あなたの推理を説明することなくこの問題を閉じるには投票しないでください。限り、私は懸念している、これはプログラミング上の質問です、それは非常にスタックオーバーフローのトピックになります。質問をさらに洗練させる必要があると思われる場合は、説明してください。私はあなたにお答えできます。

+1

SELECTクエリはデッドロックを招くロックを生成しません。あなたは本当の状況に関連するようにあなたの質問を言い換えることができますか? –

+1

@ GordonLinoff、READ_COMMITTEDのSELECTクエリはロックを生成しますが、ステートメントの実行中はロックを生成します。他の分離レベル(REPEATABLE_READやSERIALIZABLEなど)では、トランザクションの終了までロックを保持します。注意:一部のデータベースではロックを使用しないMVCCを使用していますが、これらはこの問題の対象外です。 – Gili

+1

ロックは実装の詳細です。隔離レベルは、起こりうる/起こり得ない現象を特定するだけである。 SQL Serverでは、コミットされた読み込みでクエリを選択すると、ほとんどの場合、データが読み込まれるとすぐに解放される 'S'ロックが使用されます(ステートメントの終了前)。ステートメントが終了するまでこれらのロックを保持することもできます(例:http://blogs.msdn.com/b/craigfr/archive/2007/05/31/read-committed-and-large-objects.aspx)。それ以外のときは行レベルの 'S'ロックをまったく取らない。特定のRDBMSを指定しないかぎり、ポイント1の2と3のポイントは返答できません。 –

答えて

5

https://stackoverflow.com/a/112256/14731によれば、ロック順序は実装固有の実行順序によって決まります。答えはさらに、デッドロックを防ぐための決定的な方法がないと言っています。命令型プログラミングでは、同じ順序でロックを取得することによってデッドロックを防ぐことができますが、宣言型システムでは、デッドロックが検出されたときに操作を再試行する必要があります。

さらに、私は、データベースの実行計画が生涯にわたって変化するため、デッドロックを防ぐことは技術的に不可能であると主張します。

+0

上記の「同じ順序でテーブルにアクセスするとき」という句は、更新ステートメントの順序を指しています。結合クエリのテーブルの順序は、クエリがSロックのみを作成するため、デッドロックの確率に大きな影響を与えません。同じクエリを実行する2つのトランザクションは互いにロックしません。 – nakosspy

+0

@ nakosspy、同じテーブルのセットを異なる順序で照会する2つのトランザクションは、デッドロックを引き起こす可能性があります(少なくとも、単純なDB実装の場合)。つまり、同じクエリを実行してもデッドロックは発生しないことに同意しますが、ポイントは、 'UPDATE'がないSELECTでもデッドロックが発生する可能性があることです。 – Gili

+2

素朴なデータベースの実装とはどういう意味ですか?クエリの排他ロックを取得するDB?私はこれを行うデータベースを知らない。しかし、このような「素朴な」データベースに対処する必要がある場合、大きな問題はデッドロックではなく、データの完全性とパフォーマンスです。 – nakosspy

1

私はあなたにDB2の回答を与えることができますが、私はこれも他のデータベースでも似ているはずです。まず、すべてはテーブルのlocksizeパラメータに依存します。このパラメータは、ロックされているものを定義します。あなたはlocksize = table、pageまたはrowを持つことができます。したがって、各テーブルのロックサイズに応じて、データベースはカーソルのデータをフェッチするために使用されるオブジェクト(テーブル、ページまたは行)をロックします。したがって、作成されるロックの順序は、オプティマイザに依存するアクセス・パスによって指定されます。

+0

これは、実装固有の実行計画に依存していると言いますか?その場合、質問3はどうですか? – Gili

+0

まず、これらのロックはSロックです。これは、カーソルによって使用されるページ(または行)を更新する他のトランザクションは許可されないことを意味します。カーソルを開いて分離レベルが安定していると、他の誰もカーソルが読み取るデータを変更することはできません。あなたのトランザクションはこれらのデータを変更することができます。デッドロックを最小限に抑えたい場合は、ページまたは表の行ロックを優先し、分離レベルをカーソルの安定性に設定します。 – nakosspy