私は単純なメッセージングプログラムを書いています。メッセージのテーブルがあります。メッセージのテーブルはユーザーが要求し、そのユーザーによって処理されます。どのユーザーが特定のメッセージを要求するかは予期されていないので、私が持っているすべての利用可能なメッセージのうち最初のものを選択し、そのメッセージを私が持っているテイクとしてマークするクエリが必要です。問題は、同時に2人のユーザーが同じメッセージを主張することを希望しないため、2つのステートメントを連続して実行し、プログラムに戻って次のプログラムを実行する必要はありません。文の間。セミコロンで区切って2つの連続した文を実行することができますが、最初の問合せで戻されたデータを2番目の問合せの一部として使用したいと考えています。変数は完璧ですが、私が知っている限り、SQLには存在しません。クエリ間に状態を保存する方法はありますか?状態が連続したSQLステートメント
答えて
取引がle dorfierが言うように、行くには良い方法ですが、alernativesがあります:あなたが最初の更新を行うことができ
、すなわち、ユーザIDまたは同様のメッセージにタグを付けるには。あなたは、SQL風味youreの使用に言及いけないが、MySQLで、私はそれがこのようなものに見えると思う:
WITH q AS (
SELECT TOP 1
FROM message m
WHERE user_id = 0
)
UPDATE q
SET user_id = 1
:MS SQLで
UPDATE message
SET user_id = ...
WHERE user_id = 0 -- Ensures no two users gets the same message
LIMIT 1
を、それはの線に沿って何かだろう
/B
クエリ間に状態を保存する方法はありますか?
いいえ、SQLは手続き型言語ではありません。 2つのクエリを1つのクエリとして書き直すことができます(必ずしも可能ではなく、可能であっても価値がないことが多い)か、手続き型言語でそれらを結合します。多くのSQLサーバーは、このための組み込み言語(「ストアドプロシージャ」)を提供していますが、アプリケーションで実行することもできます。
問題は、私は、同じメッセージを請求すると同時に、
使用のロックを、それを使用して2人のユーザーを望んでいないこと、です。私はあなたが使用しているSQLサーバを知っていませんが、利用可能であれば、あなたが望むものであるようにSELECT ... FOR UPDATE
という音を使用しています。
これはBEGIN TRANとCOMMIT TRANのためのものです。保護したいステートメントをトランザクション内に配置します。
おそらく一時テーブルを使用できます。
SQL自体には変数はありませんが、ほとんどすべてのRDBMS SQL拡張機能が(ほとんどの場合)?しかし、私はそれだけであなたの問題を解決する方法は本当によく分かりません。
前述のように、トランザクションは、関連のない2つのステートメントをまとめてトリック効果的にグループ化します。 の場合、デフォルトの取引レベルはとなります。 (Most?)RDBMSサーバーのデフォルト・トランザクション・レベルはREAD COMMITTEDです。これは、ユーザー2がユーザー1が読み取ったのと同じ行を読み取ることを妨げません。そのためには、REPEATABLE READまたはSERIALIZABLEを使用する必要があります。
これは古典的な並行性の問題です。一般に、それを処理する2つの方法は、悲観的なロックまたは楽観的なチェックです。REPEATABLE READトランザクションは悲観的なものになり(必要であるかどうかにかかわらずロッキング経費がかかる)、@@ ROWCOUNTをチェックすることは楽観的です(@@ ROWCOUNT = 0のときにはうまくいくと思います)。
通常、楽観的(ロックは高価です)を使用し、タイムスタンプまたはフィールドの組み合わせを使用して、私たちが思ったデータを変更していることを確認します。したがって、私の提案は、rowversionまたはtimestampフィールドをインクルードし、それをUPDATEステートメントに渡すことです。次に、@@ ROWCOUNTをチェックして、レコードを更新したかどうかを確認します。あなたがしなかったなら、戻って別のメッセージを選んでください。擬似コードで:
int messageId, byte[] rowVersion = DB.Select(
"SELECT TOP 1
MessageId, RowVersion
FROM Messages
WHERE
User IS NULL";
int rowsAffected = DB.Update(
"UPDATE Messages SET
User = @myUserId
WHERE
MessageId = @messageId
AND RowVersion = @rowVersion",
myUserId, messageId, rowVersion
);
if (rowsAffected = 0)
throw new ConcurrencyException("The message was taken by someone else");
あなたの特定のステートメントに応じて、あなただけのWHEREあなたのUPDATEステートメントで句「ユーザーIDがNULL IS」繰り返して逃げることができるかもしれません。これはBrimstedtのソリューションに似ていますが、でも、行が実際に更新されたかどうかを確認するには、@@ ROWCOUNTを確認する必要があります。
- 1. マージする方法連続した重複状態の行 - Sql Server
- 2. HttpWebRequestとHttpWebResponse:連続したクエリのログイン要求の状態を維持する
- 3. JavaのJDBC接続状態
- 4. 接続状態MySql Connector/NET
- 5. SQL GROUP BY:連続した間隔?
- 6. SQLセッション状態&Javascriptのエラー
- 7. SQLのASP.NETセッション状態
- 8. SQLセッション状態サーバーの動的接続文字列
- 9. SQL Serverアクティブ状態のスリープ状態のプロセス?
- 10. 敵にロックされた状態でユニティキャラクターが動い続ける
- 11. 3状態マルコフ連鎖プロットの作成
- 12. リクエストを介した状態の取得と永続化
- 13. 状態の取得選択した国の状態のリスト
- 14. アイデンティティ列をギャップなしで連続した状態に保つにはどうすればよいですか?
- 15. Java Socketクラスが接続状態に関して横たわっています
- 16. redux古い状態を接続する
- 17. Windows Mobile 6間欠接続状態NOPATHTODESTINATION
- 18. 状態マシンの永続性WorkFlow
- 19. アンドロイドアプリの永続状態のデザインパターン
- 20. JavaScript変数スコープ - 持続状態?
- 21. 休止状態はSchemaExportと永続ユニット
- 22. Tomcatの接続プーリング、アイドル状態の接続、接続の作成
- 23. componentWillReceiveProps状態が還元状態更新後のレンダリング状態と異なる
- 24. SQLレポートの初期トグル状態
- 25. 無効なカーソル状態(SQL例外)
- 26. ASP.Netセッション状態SQL Serverユーザーアクセス許可
- 27. ASP.NET SQL Serverの状態管理 - get appid
- 28. Linq to SQL、Ajaxポストバック、ASP.NETのページ状態
- 29. 状態分割、MongoDB、Memcached、または...を使用したASP.NET MVCセッション状態?
- 30. が休止状態