1

チーム メンバーが古い社内システムで問題に遭遇しました。ユーザーが Web ページのリンクをダブルクリックすると、ブラウザーから 2 つの要求が送信され、レースで同じレコードが 2 つのデータベースに挿入される可能性があります。調子; 最後に実行したものは主キー違反で失敗します。いくつかのソリューションとハックが提案され、議論されています。

  1. Web ページで Javascript を使用して、最初のクリックでリンクを無効にすることにより、2 回目のクリックを軽減します。これは、問題の発生を減らすための迅速かつ簡単な方法ですが、完全になくすことはできません。

  2. サーバー側でのリクエスト実行をトランザクションにラップします。これは、サーバーの負荷と問題のテーブルのロック レベルが原因で、操作のコストが高すぎると見なされています。

  3. 失敗した挿入によってスローされた主キー例外をキャッチし、それを識別して食べます。これには、(a) ベンダー ロックイン、データベース固有の例外のニュアンスを知る必要がある、(b) 正当なデータベース障害のログ記録/対処ができない可能性があるという欠点があります。

  4. 挿入が失敗した場合にレコードの更新を試行し、更新の結果をチェックして、影響を受ける 1 つのレコードが返されるようにする #3 の拡張。

考慮されていない他のオプションはありますか?見落とされていた提示されたオプションの長所と短所はありますか? すべての悪の中でどれが小さいですか?

4

5 に答える 5

5

ページの非表示フィールドに一意の識別子を配置します。指定された一意の識別子を持つ 1 つの応答のみを受け入れます。

于 2008-10-03T18:22:57.057 に答える
2

サーバーの状態を変更するために GET リクエストを悪用しているように思えます (ただし、必ずしもそうであるとは限りません)。あなたの状況には適切ではないかもしれませんが、リンクをフォーム POST に変換することを検討する必要があることを述べておく必要があります。

于 2008-10-03T18:23:17.603 に答える
1

Synchronizer Token パターンを実装する必要があります。

仕組みは次のとおりです。値 (トークン) は、リクエストごとにサーバー上で生成されます。この同じトークンをフォーム送信に含める必要があります。リクエストを受信すると、サーバー トークンとクライアント トークンが比較され、それらが同じ場合は引き続きレコードを追加できます。その後、サーバー側のトークンが再生成されるため、古いトークンを含む後続のリクエストは失敗します。

このページの中ほどに、より詳しい説明があります。

どのテクノロジーを使用しているかはわかりませんが、Struts はこのパターンに対してフレームワーク レベルのサポートを提供します。ここで例を参照してください

于 2008-11-19T10:37:17.600 に答える
0

あなたはすでに自分の質問に答えているようです。#1が唯一の実行可能なオプションのようです。

それ以外の場合は、実際には 3 つの手順すべてを実行する必要があります。データの整合性はデータベース レベルで処理する必要がありますが、データベースへのラウンドトリップを回避するためにコード内で追加のチェック (明示的なトランザクションなど) を行うと、パフォーマンスが向上する可能性があります。

于 2008-10-03T18:23:12.390 に答える
0

REF Synchronizer Token パターンを実装する必要があります。

これは Java ではなく Javascript/HTML 用です。

于 2008-11-19T10:42:49.353 に答える