問題タブ [database-concurrency]
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.
java - リレーショナル データベースで安全に同時更新を行うための適切なアプローチは何ですか?
リレーショナル データベース (現在は H2) を更新する Java アプリを作成しています。私は次のことを行うプロセスを持っています:
- 特定のデータ項目について外部システムにクエリを実行する
- インポート ログ テーブルを確認して、これらのアイテムが既にシステムにインポートされているかどうかを確認します。そうでない場合:
- 新しいデータ項目をさまざまなテーブルにインポートします。
- インポート ログ テーブルに新しいレコードを書き込みます。
このプロセスは、異なるスレッドで同時に実行される場合があります。2 つのスレッドが両方ともインポート ログをチェックし、そこに何も見つからず、両方ともデータ項目を挿入しようとする問題を回避したいと思います。
良いアプローチは何ですか?私は検討してきました:
- SERIALIZABLE トランザクション分離の使用。
- インポート ログの一意のインデックス制約に依存して、トランザクションの 1 つをエラーおよびロールバックします。
- プロセスを Java アプリの 1 つのスレッドに限定します。
さまざまな理由から、上記のどれもあまり魅力的ではないようです。よりうまく機能する可能性のある別のアプローチはありますか?
sql - Oracle トランザクションと読み取り一貫性
12 時までに sql*plus を使用して友達と一緒に登録したすべての人に宝くじを提供していると考えてください。タイムスタンプを格納する列はなく、各行の名前のリストだけです。人 m1 は、11:59 より前にチケットを挿入してコミットしました。
彼は 11:59 に自分の (行) 詳細の更新を開始し、メイドを宝くじリストに追加します (コミットする必要があるだけです)。m2 を実行する別の人が insert ステートメントを実行し、11:59 に最初の挿入を開始します (自分自身のためだけに) (コミットする必要があるだけです)。2000万行の巨大なテーブルです。
現在12です。これを読み取りコミット分離レベルと考えてください。
抽選バッチが開始され、登録ユーザーが他のテーブルに移動しました。その後 (次のナノ秒の可能性が非常に高い)、m1 と m2 の両方がコミットします。
私の select ステートメントはバッチで m1 のメイドと m2 を宝くじ当選者リストに追加しますか?
応答中は、scn(システム変更番号)、ファントム、反復不可能な読み取りを考慮してください。
mysql - MySQL(innodb)への同時挿入
t_log
databaseにテーブルがあるとしますTest
。t_log は次のようになります。
フィールドF_action
が 1 と 2 のようないくつかの特定の値しかとれないとします。 F_action
=1 レコードの場合、対応する値F_trans_id
は互いに異なる必要があります。F_action
=2 レコードの場合、対応はF_trans_id
同じ値を取ることができます。
たとえば、次の表のようなレコードが有効である必要があります
ただし、次のようなレコードは有効ではありません
に対する一意の制限F_trans_id
は の特定の値に依存するF_action
ため、単に F_trans_id および F_action に対して一意のインデックスを構築することはできません。
一貫性を保つために、t_log へのレコードの挿入は、次のようなトランザクションに入れられます。
ただし、同時実行性の高い環境では、2 つの挿入トランザクションがほぼ同時に到着する場合があります。見つかったレコードは有効であり、挿入します。次にt_log
、無効な 2 つのレコードがあります。
この種の無効なレコードを防ぐ良い方法はありますか? ありがとうございました。
sql - 複数のタスクを使用して複数のリレーショナル テーブルにデータを挿入する方法
まず、プログラミング初心者です。
多くのタスクを使用するプログラムを作成しようとしています。これらのタスクは、複数のリレーショナル テーブルにデータを挿入します。(私はSQLサーバーを使用しています)
しかし、タスクが最初のテーブルにデータを挿入し、最後に挿入された ID ID を他のリレーショナル テーブルで使用する場合、他のタスクがデータを最初のテーブルに挿入し、その場合、最後に挿入された ID ID が変更されたため、最初のタスクは間違った (2 番目のタスクによって変更された) 最後に挿入された ID ID を使用すると思います。
トランザクション全体をロックするシリアル化可能なロックを使用することを考えましたが、それはうまくいくと思いますが、これはパフォーマンスにも影響を与える可能性があります。
では、パフォーマンスを損なわないようにするにはどうすればよいでしょうか?
java - 並行環境でのデータベース接続リークのデバッグ
私は現在、もともと高負荷向けに構築されていなかったプロジェクトに取り組んでいます。
私の問題は、ストレス テスト (30 ユーザー) 中のある時点で、アプリケーションが「動かなくなった」ように見え、リリース時に多くの例外を吐き出すことです。Unable to get managed connection for [MY_DS]
1 人のユーザーのみを実行すると、魅力的に機能するので、同時実行性と関係があります。また、1 回の実行の最後にクローズされていない DB 接続があるかどうかも確認しましたが、何もなかったので、通常の使用では接続リークはありません。
私の疑いは、open メソッドと close メソッドに向けられています (これらは静的であるため)。メソッドは次のとおりです。
これは、SQL Server 2008 によってバックアップされた JBoss EAP 6.2.0 で実行される EE アプリケーションです。
誰かが私を正しい方向に向けて、解決策を見つけることができる場所を見つけることができますか?
oracle - Oracle データベース トランザクションは、このシナリオで役立ちますか?
Oracle データベース (11g リリース 2) を使用しています。複数の接続が同時に次のことを行っていると想像してください。
- 取引開始
- 一意の値のテーブルに特定の値が存在するかどうかを確認する
- 値が存在しない場合は、挿入します
- トランザクションをコミットする
競合を防ぐ唯一の方法は、他の接続が現在 4 ステップ シーケンスを実行している間、接続が上記の 4 ステップ シーケンスを実行するのをブロックすることだと私には思えます。
トランザクションは、Oracle でこの種の広範なロック/ブロックを実現できますか?
このシナリオに対処する最善の方法について、回答とアドバイスをお寄せいただきありがとうございます。