問題タブ [transaction-isolation]
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.
mysql - 分離レベルが READ COMMITTED の場合、MySQL InnoDB は UNION を使用して複数のテーブルで SELECT の一貫したスナップショットを作成しますか?
次のような 2 つのテーブルを考えてみましょう。
これらは単純な例にすぎません...実際のシステムでは、両方のテーブルにかなり多くの列と行があります (現在の行は 10,000 行以上、履歴は 100 万行以上)。
クライアント アプリケーションは継続的に (1 秒間に数回) 新しい行を現在のテーブルに挿入し、古い既存の行を現在のテーブルから履歴に "移動" します (1 回のトランザクション内での削除/挿入)。
このアクティビティでクライアントをブロックすることなく、2 つのテーブル全体で部門ごとの値の一貫した合計を取得する必要があります。
トランザクション分離レベルを REPEATABLE READ に設定すると、次のことができます。
に続く
2 つの結果セットを合計します。しかし、各クエリはそれぞれのテーブルへの挿入をブロックします。
分離レベルを READ COMMITTED に変更し、同じ 2 つの SQL を実行すると、挿入のブロックを回避できますが、クエリ中に現在のエントリから履歴に移動すると、エントリが二重にカウントされるリスクがあります (各 SELECT が独自のスナップショットを作成するため)。
ここに質問があります....UNIONを実行すると、分離レベルREAD COMMITTEDで何が起こりますか:
MySQL は両方のテーブルの一貫したスナップショットを同時に生成しますか (それにより二重カウントのリスクを取り除きます)、それとも最初に 1 つのテーブルのスナップショットを取得し、しばらくしてから 2 番目のテーブルのスナップショットを取得しますか?
java - 分離が「コミット済み読み取り」に設定されているにもかかわらず、同時 DB 接続が互いにコミットされていない変更を参照するのはなぜですか?
トランザクションの分離レベルを使用してさまざまな同時実行の問題に対処する方法を理解するために、いくつかのテストを行おうとしています。から始めましTRANSACTION_READ_COMMITED
たが、最も単純なシナリオでは期待どおりに動作しません。コードは次のとおりです。
ここでは、2 つの同時接続をセットアップし、両方でトランザクションを開始し、最初の接続で変更を行い、2 番目の接続ではそれらが表示されないことを期待しています。これは機能しません。接続 1 で行われたコミットされていない変更は、接続 2 に表示されます。
インメモリデータベースで組み込みモードで実行されているHSQLDB 2.3.2を使用しています。私の selectAll/insert ヘルパー メソッドの実装は次のとおりです。
完全なテストはここにあります: https://gist.github.com/loki2302/aad49a5a2c26d5fda2b3
このコードに問題がありますか、それとも HSQLDB が本来の動作をしていませんか?
更新: wiki を読み直した後、ここでの私の考えは間違っていると思います。ここに表示されるのは「ファントム リード」です。READ_COMMITTED
ファントム読み取りが発生しないことを保証するものではありません。代わりに確認する必要があるのは、テーブルを 1 行で事前に生成し、更新して、変更がコミットされない限り、connection1
この変更が表示されないようにすることです。connection2
さらに、この変更がコミットの直後に見えるようになることは一般的に保証されていません。見えるようになるかもしれませんが、保証されていません。
jpa - @Transactional "READ_UNCOMMITTED" で分離レベルを設定する方法。私はEclipseLink 2.5.1-RC1を使用しています
2番目のトランザクションの例外が古いトランザクションではなく新しいトランザクションのみをロールバックするように、進行中のトランザクション内で新しいトランザクションを開始する必要があります。
これは、次のように2番目のトランザクションで伝播属性を設定することで行っています:
@トランザクション (伝播 = 伝播.REQUIRES_NEW)
これにより新しいトランザクションが作成されましたが、新しいトランザクションは最初のトランザクションのコミットされていないデータを読み取り (ダーティ読み取り)、そのデータも更新する必要があります。これは、分離属性を次のように設定して実行しようとしています。
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation=Isolation.READ_UNCOMMITTED)
これにより、例外 - InvalidIsolationLevelException がスローされ、「標準 JPA はカスタム分離レベルをサポートしていません - JPA 実装には特別な JpaDialect を使用してください」というメッセージが表示されます。
JpaDialect の実装に役立つものはありますか? Eclipse Link 2.5.1 を使用しています。
または、新しいトランザクションを開始する前に、最初のトランザクションをどのように閉じることができますか? 最初のトランザクションは閉じられているため、2 番目のトランザクションは、最初のトランザクションによってコミットされたデータを問題なく読み取ることができます。
mysql - ロックされている行の読み取りを待機します -- トランザクションの分離
テーブルの行をロックして、その行に対する他の読み取り操作がロックが解除されるまで待機するようにしたいのですが、テーブル全体がロックされるのを避けたいと考えています。
次のテーブルがあります(InnoDB)
次のトランザクションを実行して、行のロックを取得します
そして、次のクエリでロックが解放されるのを待ちたいと思います
それを行うには、私が見つけた唯一の方法は、次のようにSELECTを実行することです
ロックが解放されるのを待ちSELECT
ますが、このテーブルの autocommit と分離レベルの設定を前に付ける必要があります。
テーブルレベルautocommit=0
でtransaction-isolation = SERIALIZABLE
のみ構成する方法はありますか?
私は設定できることを知っています
でmy.cnf
、しかし、他のテーブルやスキーマで行われる他の操作には影響を与えたくありません。
参照:
oracle - 2つのトランザクション間のSQL内部クエリ選択
2 つのトランザクション間の内部クエリ選択読み取りを理解するのに助けが必要
クエリが実行されるたびに SER_NUM = SER_NUM + 1 を更新しています。リクエストが非常に激しいため、1 秒あたり数千のリクエストが発生する可能性があります。
問題は、2 つのクエリ トランザクションが内部選択から同じ値を読み取り、2 つのトランザクションが同じ値を更新する可能性があるということです。
Transaction-1 が更新を完了するまで、Transaction-2 に読み取りを待機させる簡単な方法はありますか?
オラクルのドキュメントからわかるように、デフォルトの分離はコミットされた読み取りです
(Oracle Databaseは、問合せによって読み取られたデータが他のトランザクションによって変更されることを防止しません。そのデータは、問合せの2回の実行の間に他のトランザクションによって変更される可能性があります。したがって、特定の問合せを2回実行するトランザクションでは、繰返し不能読取りとファントムの両方が発生する可能性があります。 )
これを達成するための最善のアプローチに関する提案はありますか?
postgresql - スタンバイで実行される Repeatable Read トランザクションは、どのように一時的な状態を確認できますか?
トランザクションの分離レベルに関する PostgreSQL のドキュメントでは、以下を読むことができます。
マスターのシリアライズ可能トランザクション内ですべての永続的なデータベース書き込みを実行すると、すべてのスタンバイが最終的に一貫した状態に到達することが保証されますが、スタンバイで実行される反復可能読み取りトランザクションは、マスターでのシリアライズ可能トランザクションのシリアル実行と矛盾する一時的な状態を確認することがあります。主人。
上記のテキストはhttp://www.postgresql.org/docs/9.4/static/transaction-iso.htmlの下部にあります
ホット スタンバイで実行された Repeatable Read トランザクションが一貫性のない一時的な状態になる可能性があるのは、どのような状況ですか?
java - データベースの select ステートメントでの同時実行の問題
問題があり、この状況で database isolationtype == Serializable を使用することを考えていますが、一連の記事を読んだ後でも、それが以下の問題の解決策であるとは確信していません。
セットアップ:
テーブルがLAN
あり、クライアントからの入力に基づいて一致する値を選択します。
LAN
ビジネス ロジックでは、LAN から一致する行を選択し、別のテーブルを保存する必要があります。LAN_Assignment
LAN_割り当て
select ステートメントを実行すると、LAN テーブルから一致する行を取得し、それを lan_assignment テーブルに割り当てます。
ここで、クライアント (クラスター内の任意のサーバーである可能性があります) から 5 つの要求が送信された場合、それらはすべて最初に使用可能な LAN を選択し、それを他のテーブルに保存します。
LAN を取得した最初の要求が、クライアントからの 2 番目の要求によって選択されないようにするにはどうすればよいですか?
PS: select ステートメントとビジネス ロジックは、ここで説明したように単純ではありません。LANを選んでLan_assignmentに保存するなど条件はいろいろありますが、
ありがとうございました
sql - 同時干渉から隔離して、テーブル内の複数の行を一貫して更新する
異なるデータベースにある 2 つのテーブルを同期するタスクがあります。そのため、ソース テーブルで発生するすべての挿入、更新、および削除について、これらの変更を宛先テーブルにレプリケートする必要があります。宛先テーブルは、ソース テーブルのクローンになります。これを実装するために、ソース テーブルにトリガーをインストールすることにしました。
しかし、複数のユーザーが同時にテーブルを使用しており、トリガーが宛先テーブルの複数の行を更新する必要がある場合があるため、これらの更新の同時実行の側面について深く懸念しています。トリガーで実行される変更の観点からは、ロジックが正しいと確信していますが、分離レベルについてはそうではありません。私はこれについての専門家ではないからです。
そこで、宛先テーブルでの挿入と更新を担当するトリガーを示し、同時実行の側面に関して問題があるかどうかを確認するように依頼します。その前に、表といくつかのユースケースをお見せしましょう。
これはソース テーブルです (簡単にするために、宛先テーブルが同じ構造を持つと仮定します)。
ここで、宛先テーブルに次の行があるとします。
ID 6 の親部門を ID 4 を指すように変更したいと考えています。変更後、行は次のようになります。
したがって、ご覧のとおり、更新によって影響を受けたのは 1 行だけです。ここで、id 1 (つまり NULL) の親 ID を変更して、id 6 (元の行セット内) を指すようにしたいとします。したがって、変更後は次のようになります。
したがって、この場合、複数の行を更新して階層を修正する必要がありました。
したがって、複数の行への変更を一貫して実行したいのですが、トリガーがこれを考慮していないと思います。これがトリガーです:
たぶん、これらの行を次から変更します。
これに:
現在の行の問題は解決しますが、更新が必要な他の行の問題は解決しません。
トリガーが同時に正しく動作するように修正するために何をすべきかを誰かが教えてくれたら、とてもうれしいです。
前もって感謝します。
マルコス
postgresql - シリアライゼーション失敗の PostgreSQL 汎用ハンドラー
これは this oneからのフォローアップの質問なので、ロック (ブロック) を使用できることはわかっていますが、述語ロックとシリアル化可能なトランザクション分離を使用したいと考えています。
私が欲しいのは、関数/クエリを X 回再試行するシリアル化エラーの汎用ハンドラーです。
例として、私はこれを持っています:
したがって、mytest()
同時に直接呼び出すと、最後のコミットでシリアライゼーション エラーが発生します。
私が呼び出すmyretest()
と、例外が発生する5回目の試行まで実行を試みる必要mytest()
があります。
したがって、ここに 2 つのポイントがあります (ポイント 2 もポイント 1 を無効にする可能性があります)。
myretest()
期待どおりに動作しません。同時スレッドが終了した後でも、すべての反復で serialiation_failure 例外が発生します。トランザクションを「リセット」するために追加する必要があるものはありますか?myretest()
「ラッパー」関数自体を必要とせずに、システム内のすべての呼び出された関数に適用されるように、これを (ロジック) ジェネリックにするにはどうすればよいですか?