問題タブ [idempotent]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
database - ブラウザがリロード/バックを行ったときにデータベースが再度書き込まれるのを防ぐにはどうすればよいですか?
データベース (Perl CGI & MySQL) に書き込む小さな Web アプリを作成しています。CGI スクリプトはフォームから情報を取得し、それをデータベースに書き込みます。ただし、Web ブラウザーで [再読み込み] または [戻る] をクリックすると、データがデータベースに再度書き込まれることに気付きました。私はこれをしたくありません。
この場合、データの書き換えを防ぐ最善の方法は何ですか?
function - 副作用のない決定論的関数の用語は?
特定のタイプの機能に適切な用語が必要です。
入力と出力がデータベース トランザクションのスコープ内に含まれる関数を SQL データベースに記述するとします。
つまり、この関数をデータベース トランザクションのスコープ内で呼び出すと、関数によって使用されるすべてのデータが同じスコープ内で使用可能になります。データベース テーブルにクエリを実行できますが、ファイル システムからファイルを読み取ったり、Web サイトに ping を実行したりすることはできません。REPEATABLE READ
分離を使用して 1 つのトランザクション内で関数を 2 回呼び出すと、同じ結果が得られるはずです。クライアントはデータベースに変更を加えています。
同様に、同じトランザクション スコープ内を除いて、この関数には副作用がありません。データベース トランザクションの範囲外での状態の変更は許可されていません。関数は、電子メールを送信したり、ファイルシステムに書き込んだり、値を に保存したりすべきではありませんmemcached
。関数がデータベース内のデータを変更する場合、それは問題ありません。呼び出し元のトランザクションがロールバックされた場合、関数の効果があまりにも大きくなるためです。 .
関数の引数は、基本的に定数として使用されるため、問題ありません。
このタイプの関数の適切な用語は何ですか? 「決定論的」は実際には十分に具体的ではないようです。このクラスの機能をどのように説明しますか?
ご回答ありがとうございます。冪等性が最も近くなるので、それを受け入れられた回答としてマークしました。しかし、あなたのそれぞれは、関係なく私から賛成票を獲得しました。
純粋な関数には副作用がなく、その結果は引数のみに基づいています。同じ引数が与えられた結果は常に同じです。私が考えているデータベース関数はデータの状態に基づいている可能性があり、関数はデータの状態にも影響を与える可能性があるため、これは機能しません。
べき等関数は、データの状態に基づいて結果を返すことができ、データの状態が同じであれば、結果は常に同じになります。しかし、これは私が念頭に置いていることには正確には機能しません。冪等関数の効果は、関数が何回呼び出されても結果が変わらない必要があります。ただし、トランザクションの分離内で行われた変更と、その範囲外で行われた変更の間に区別はありません。
rest - HTTP DELETEの観点からべき等性を表示する正しい方法は何ですか?
私は最近、HTTP 1.1仕様を読み、それをRESTに関連付けることに多くの時間を費やしました。HTTP DELETEメソッドには、その「べき等性」と安全性に関して2つの解釈があることがわかりました。これが2つのキャンプです:
HTTP DELETEを使用してリソースを削除し、それが成功した場合(200 OK)、そのリソースをN回削除しようとすると、それらの削除呼び出しごとに成功メッセージ(200 OK)が返されます。 。これがその「無力さ」です。
HTTP DELETEを使用してリソースを削除し、成功した場合(200 OK)、そのリソースを再度削除しようとすると、リソースが削除されたため、エラーメッセージ(410 Gone)が返されます。
仕様では、DELETEはべき等であると述べていますが、べき等イベントのシーケンスは依然として副作用を引き起こす可能性があるとも述べています。私は本当に2番目のキャンプが正しいと感じています、そして最初のキャンプは誤解を招きます。以前に削除されたリソースを削除する原因であるとクライアントに考えさせることで、どのような「安全性」を導入しましたか?
最初のキャンプにはたくさんの人がいて、そのテーマについて何人かの著者がいるので、人々を最初のキャンプに導く感情以外の説得力のある理由があるかどうかを確認したいと思いました。
security - nonce を含む電子メールのアクティブ化/登録/パスワード リセット リンクのベスト プラクティスは何ですか
アプリケーションは電子メールを送信して、ユーザー アカウントを確認したり、パスワードをリセットしたりします。以下が本来あるべき姿であると信じており、参照と実装を求めています。
アプリケーションがユーザーのアドレスを確認するために電子メールでリンクを送信する必要がある場合、私の見解によると、リンクとアプリケーションによるリンクの処理には、次の特性が必要です。
- リンクのリクエスト URI にnonce
http://host/path?nonce
が含まれています ( )。 - リンクをたどる (GET) と、ユーザーにはフォームが表示され、オプションで nonce が表示されます。
- ユーザーが入力を確認します (POST)。
- サーバーはリクエストを受け取り、
- 入力パラメータをチェックし、
- 変更を実行し、
- ノンスを無効にします。
これはHTTP RFC on Safe and Idempotent Methodsに従って正しいはずです。
問題は、このプロセスには 1 つの追加のページまたはユーザー アクション (項目 3) が含まれていることです。これは、多くの人が (無用ではないにしても) 不必要だと考えています。このアプローチを同僚や顧客に提示するのに問題があったため、より広範な技術グループからの意見を求めています。POST ステップをスキップすることに対して私が持っていた唯一の議論は、ブラウザーからのリンクのプリロードの可能性でした。
- アイデアをよりよく説明し、技術者ではない人でも納得できるような参考文献はありますか (ジャーナル、ブログなどからのベスト プラクティス)。
- このアプローチを実装している参照サイト (できれば人気があり、多くのユーザーがいるサイト) はありますか?
- そうでない場合、文書化された理由または同等の代替手段はありますか?
ありがとう、
カリエム
詳細は省略
主要な部分は短くしましたが、意図的に省略した詳細についての議論を減らすために、いくつかの仮定を追加します。
- メールの内容は、この議論の一部ではありません。ユーザーは、アクションを実行するにはリンクをクリックする必要があることを知っています。ユーザーが反応しない場合、何も起こらないこともわかっています。
- ユーザーにメールを送信する理由や通信ポリシーを示す必要はありません。ユーザーは電子メールを受信することを期待していると想定します。
- ナンスには有効期限のタイムスタンプがあり、重複を減らすために受信者の電子メール アドレスに直接関連付けられます。
ノート
OpenID などにより、通常の Web アプリケーションは標準的なユーザー アカウント管理 (パスワード、電子メールなど) の実装から解放されますが、それでも一部の顧客は「自分のユーザー」を望んでいます。
奇妙なことに、満足のいく質問も答えもここではまだ見つけていません。私がこれまでに見つけたもの:
language-agnostic - べき等演算とは何ですか?
べき等演算とは何ですか?
html - フォームで post メソッドを使用するとエラーが発生する
フォームを次のページに渡すときにpostメソッドを使用するとnullになります この質問の リンクテキストの繰り返し
IN testjsp.jsp では、実行できない prio 変数とその prio 変数を prin しようとしています。他のサーバー側コンポーネントで変数 prio にアクセスしたいだけで、post メソッドも使用したいだけです。
これは冪等性に何らかの関係がありますか? testjsp ページで変数 prio にアクセスできなかった理由がわかりません。
messaging - 複数の競合するコンシューマーとのメッセージの冪等性を確保するにはどうすればよいですか?
複数の競合するコンシューマーが分散しており、それぞれが同じ (トランザクション) キューからメッセージを引き出しています。各コンシューマをべき等レシーバとして実装したいので、重複が到着した場合でも、同じメッセージを (すべてのコンシューマにわたって) 2 回以上処理することはありません。複数のコンシューマーでこれを達成するにはどうすればよいですか?
私が最初に考えたのは、各メッセージをキューに入れる前に何らかの方法で連続したシーケンス番号を生成し、共有データベース テーブルを使用してコンシューマー間の作業を調整することです。つまり、consumer#1 は msg#1 を処理し、DB テーブルに「msg#1 が処理されました」という行を書き込みます (耐久性を確保するためにデータベースに入れたい)。コンシューマーは、メッセージを処理する準備ができると、キューで次に使用可能なメッセージを調べ、共有 DB テーブルを調べて、これが次のメッセージであるかどうかを判断します。もしそうなら、それはキューから外されます。そうでない場合、それは無視されます。
このように、処理された最後のメッセージを保存するだけでよく (すべてのメッセージに連続したシーケンス番号があるため)、ネゴシエートされた「ウィンドウ」サイズで受信したすべてのメッセージの ID を保存するバッファーを使用する必要はありません。メッセージは常にシリアルに処理されます (これは、このシナリオで必要なことです)。
より良い方法があるかどうかだけ知りたいですか?メッセージを処理する必要があるときはいつでも、データベースにクエリを実行するコストが心配です。
答えが「フレームワークに依存する」である場合、MSMQ を念頭に置いていました
subsonic - SQL 2008バックエンドでsubsonicを使用してべき等の挿入行を実行するにはどうすればよいですか?
SQL 2008バックエンドでsubsonicを使用してべき等の挿入行を実行するにはどうすればよいですか?
例えば
名前が主キーであるテーブル「Colors」があります。
エラーをトラップできることはわかっていますが、MySqlでREPLACEのようなことをしたいと思います
scalability - 書き込み操作をべき等にする方法は?
最近リリースされたGizzardシャーディングフレームワークに関する記事をTwitterで読んでいます(http://engineering.twitter.com/2010/04/introducing-gizzard-framework-for.html)。高い信頼性を確保するには、すべての書き込み操作がべき等でなければならないと記載されています。
ウィキペディアによると、「べき等演算は、結果を変更せずに複数回適用できる演算です。」ただし、IMHOの場合、Gizzardの場合、べき等の書き込み操作は、順序が重要ではない操作である必要があります。
さて、私の質問は次のとおりです。書き込み操作をべき等にするにはどうすればよいですか?
私が想像できる唯一のことは、各書き込みにバージョン番号を付けることです。たとえば、ブログシステムでは、各ブログに$blog_idと$contentが必要です。アプリケーションレベルでは、常にこのwrite($ blog_id、$ content、$ version)のようなブログコンテンツを書き込みます。$ versionは、アプリケーションレベルで一意であると判断されます。したがって、アプリケーションが最初に1つのブログを「Helloworld」に設定しようとし、次にそれを「Goodbye」にしたい場合、書き込みはべき等です。このような2つの書き込み操作があります。
これらの2つの操作は、DB内の2つの異なるレコードを変更することになっています。したがって、これら2つの操作が何度実行され、どのような順序で実行されても、結果は同じです。
これは私の理解です。私が間違っている場合は訂正してください。
rest - RESTfulべき等
ROA(リソース指向アーキテクチャ)を利用したRESTfulWebサービスを設計しています。
サーバーがリソースキーを指定した場合に、新しいリソースを作成するPUT要求のべき等性を保証する効率的な方法を見つけようとしています。
私の理解では、従来のアプローチは/CREATE_PERSONなどのタイプのトランザクションリソースを作成することです。新しい個人リソースを作成するためのクライアント/サーバーの相互作用は、次の2つの部分になります。
ステップ1:新しいPERSONリソースを作成するための一意のトランザクションIDを取得します:::
ステップ2:トランザクションIDを使用して一意であることが保証されているリクエストに新しい個人リソースを作成します:::
このアプローチで私が目にする問題は、新しいPERSONリソースを作成する単一の操作を実行するために、サーバーに2つの要求を送信する必要があることです。これによりパフォーマンスの問題が発生し、ユーザーがクライアントがリクエストを完了するのを待つ可能性が高くなります。
リクエストごとにtransaction-idを事前送信するなど、最初のステップを排除するためのアイデアをハッシュ化しようとしていますが、私のアイデアのほとんどには他の問題があるか、アプリケーションのステートレス性を犠牲にする必要があります。
これを行う方法はありますか?
編集::::::
最終的に解決したのは、クライアントがUUIDを取得し、それをリクエストと一緒に送信することでした。UUIDは、16バイト(2 ^ 128)のスペースを占める非常に大きな数です。プログラミングマインドを持っている人が直感的に考えるかもしれないこととは反対に、UUIDをランダムに生成し、それが一意の値であると想定することは一般的に受け入れられています。これは、可能な値の数が非常に多いため、同じ数の2つをランダムに生成する確率が十分に低く、事実上不可能であるためです。
注意点の1つは、クライアントがサーバーにUUIDを要求するようにしていることです(GET uuid/
)。これは、クライアントが実行されている環境を保証できないためです。クライアントに乱数ジェネレーターをシードするなどの問題が発生した場合は、UUIDの衝突が発生する可能性があります。