oracle と innodb を使用したシナリオでテーブルのデッドロックを最小限に抑える
-
25-09-2019 - |
質問
トランザクション内で 1 ~ 3 つのテーブルを更新する関数が 35 個あります。ただし、更新を実行するだけでなく、クエリも実行します。
- 表 1 では、行更新のみのアクションといくつかのクエリが実行されます。
- テーブル 2 は、既存の行に対してクエリと行レベルの更新を行い、場合によっては行の削除と追加を行います。テーブル 2 には、行の削除、挿入、および更新の前後にトランザクション内でクエリが含まれる場合があります。
- 表 3 は、上記の表 2 のアクションの結果に基づいて行を更新します。
私の最初のアクションは、テーブル 3 の更新が最後にすべて完了していることを確認することです。
テーブル 1 は他の 2 つのテーブルから独立しており、おそらく最初または最後になる可能性があります。したがって、表 2 は表 3 が変更される前に指定する必要があります。
最初の懸念は、表 2 のアクションでは、クエリを実行し、次に更新を実行し、さらにクエリを実行し、その後さらに更新を行う場合があることです。これを行わないようにコードを再編成する必要がありますか?
2 番目の懸念は、表 3 はサーブレット スレッドが高速でなければならないテーブルであるということです。テーブル 3 は、それ自体で単純なクエリに使用されます。しかし、行レベルのロックがそれらのクエリを停止するようです。
必要に応じて、上記のテーブル セット メンテナンス コードを 1 つのスレッドから単一のクラスター全体のプロセスに配置できます。更新の速度は関係ありません。テーブル 3 に対するクエリが高速であるというだけです。そして行き詰まりが決してないということ。
Oracle と Innodb の違いがわからないので、そこに質問があります。(後で Oracle にアップグレードする予定です。)
基本的に、何に注意すべきかについてのヒントを探しています。もちろん、各アップデーター関数の開始時にテーブル 2、次にテーブル 3 に完全なテーブル ロックを強制することもできますが、そうすると Table3 サーブレット クエリ スレッドに影響が及びます。したがって、それは解決策ではないようです。
また、テーブル 2 自体に関連して、一部の関数がクエリ、クエリに基づいた更新、更新に基づいた新しいクエリ、そしてテーブル 3 への更新への結果のフローを含む追加の更新を行うことも心配です。これは本当に厄介なようです。
おすすめは?アンディ
2 つのテーブルの同じ行に対して同時に更新が行われる可能性があるため、同じ順序で更新がテーブルに適用されるように注意しました。テーブルの 1 つに 2 つのインデックスがあり、インデックスを更新するにはテーブル ロックが必要なようですか?一部の関数は、繰り返しループでテーブル 1 をクエリし、テーブル 1 を更新し、オプションでテーブル 2 をクエリし、次にテーブル 2 を更新します。このテーブルには、すべてのコンテンツのツリー内のすべての親子関係が保持されているため、すべてのユーザーにわたって大量の更新が行われます。
解決
あなたはFOR UPDATEを使用しない限り、まず、Oracleでクエリが(と私はInnoDBのを信じて)ロックを取ることはありません。
第二に、私はあなたのアプリケーションのスケールのいずれかのアイデアを得ることはありません。あなたが持っているどのように多くの同時トランザクション期待していますか?あなたは彼らが同じ行を更新することを期待していますか?
デッドロックに苦しむ可能性があるアプリケーションの並べ替えは、(新しいショーは予約のために利用可能になる)、特に高同時実行状況では、予約や発券システム(例えば、人々が劇場で同じ座席を予約しようとしている)です。
あなたのアプリケーションは、このプロファイルに適合した場合は、、あなたはおそらくデッドロック状態を予測したいです。しかし、私は少なくとも、単に、エラーをトラップロールバックし、そのトランザクションを再しようと考えるでしょう。あなたのテーブル構造、関係および更新基準に、より詳細に入る場合には、ロックのための適切なポイントが明らかになることがあります。