Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.
トランザクションのブロックによって、「デッドロック」が起こる可能性があります。デッドロックとは、トランザクションのまとまりで、そのどれもが処理を進行できない状態をいいます。
デッドロックが発生する理由は次の 2 つです。
環状ブロックの競合 トランザクション A がトランザクション B にブロックされ、トランザクション B がトランザクション A にブロックされている状態。この状態から脱け出すには、どちらかのトランザクションをキャンセルします。同様の状況は 3 つ以上のトランザクションが環状にブロックされた場合にも発生します。
トランザクションのデッドロックを排除するために、SQL Anywhere はデッドロックに関わっている接続を選択し、その接続でアクティブなトランザクションの変更をロールバックして、エラーを返します。SQL Anywhere は内部のヒューリスティックを使用してロールバックする接続を選択し、blocking_timeout によって決められた残りのブロックの待機時間が最も短い接続を優先します。すべての接続が永久に待機するように設定されている場合は、サーバーによってデッドロックが検出された接続を、犠牲にする接続として選択します。
すべてのワーカーがブロックされています。 トランザクションがブロックされても、ワーカーは放棄されたわけではありません。たとえば、データベースサーバーが 3 つのワーカーに設定されており、トランザクション A、B、C が現在要求を実行していないトランザクション D によってブロックされると、これ以上使用できるワーカーがなくなるため、デッドロック状態が発生します。この状況は、スレッドデッドロックと呼ばれます。
データベースサーバーに n ワーカーを設定したと想定します。n-1 の数のワーカーがブロックされているときに最後のワーカーをブロックしようとすると、スレッドデッドロックが発生します。データベースサーバーのカーネルは、最後のワーカーをブロックすることを許可できません。ブロックすることによって、すべてのワーカーがブロックされ、データベースサーバーがハングするためです。代わりに、データベースサーバーは最後のワーカーをブロックしようとしたタスクを終了し、その接続でアクティブなトランザクションの変更をロールバックして、エラー (SQLCODE -307、SQLSTATE 40W06) を返します。
数十または数百の接続のあるデータベースサーバーでは、データベースのサイズまたはブロックが原因で、多数の要求の実行時間が長くなる場合、スレッドデッドロックが発生することがあります。この場合、データベースサーバーのマルチプログラミングレベルを高くすることが、適切な解決法となることがあります。また、アプリケーションの設計によって、過度な競合または意図しない競合が発生し、スレッドデッドロックの原因となる場合もあります。この場合、アプリケーションでより大きなデータセットを使用するようにすると、問題が悪化することがあります。データベースサーバーのマルチプログラミングレベルを高くしても、問題は解決されないことがあります。
サーバーが使用するデータベーススレッドの数は、個々のデータベースの設定によって異なります。
ブロックされているユーザーの判別Sybase Central からデッドロックの表示