問題タブ [deadlock]
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 - C3p0 での順序のロック
c3p0 を使用して、アプリケーションでのデータベース接続の作成と破棄をログに記録しようとしていますConnectionCustomizer
。その中に、次のようなコードがあります。
私はデッドロックに陥っています。c3p0 のライブラリには、同期メソッドを使用する少なくとも 2 つのオブジェクトがあり、意図したロック順序を指定していないようです。接続をログに記録すると、ロックがかかっていてC3P0Registry
、最終的にはPoolBackedDataSource
(単純にデータソースのリストを作成すると、ハッシュコードにアクセスしてロックが発生します)。
接続プロバイダーをシャットダウンする ( を呼び出すC3P0ConnectionProvider.close()
) と、ロックが逆の順序で呼び出されます。しかし、子データソースがシャットダウンされている間、ログがトリガーされています。その結果、デッドロックが発生します。
私がc3p0ライブラリに行っている呼び出しは両方とも有効で、予想される呼び出しのようです:
C3P0ConnectionProvider.close()
C3P0Registry.getPooledDataSources()
また、(ドキュメントに明示的に記載されていない限り)独自のロック戦略を管理するのはライブラリの責任であるように思われます。(これは誰かを責めるために言っているのではありません..ベストプラクティスについての私の理解を確認するためだけです)
この問題にどのように対処すればよいですか? c3p0 は最新のメカニズムではなく同期メソッドを使用しているため、実際にロックをテストすることはできません。
DataSource
クロージング コードから、最初にC3P0Registry
ロックを取得してからDataSource
. 私は正しいロック順序を推測していますが、それが快適かどうかはわかりません。
ロギング呼び出しのロック順序を逆にすることはできないと思います。C3P0Registry
のリストを取得するにはが必要なので、それらへの参照を取得するために最初にロックしDataSources
ないと をロックできませんでした。DataSources
C3P0Registry
もちろん、別の解決策は、すべての c3p0 の上に別のより高いレベルのロックを提供することです。接続プールの場合、それはポイントを無効にしているようです。
今のところ、ログをロールバックしています。助けてくれてありがとう。
sql-server - 選択/更新または複数の選択の間で SQL Server がデッドロックする
SQL Server のデッドロックに関するすべてのドキュメントでは、操作 1 がリソース A をロックしてからリソース B にアクセスしようとし、操作 2 がリソース B をロックしてリソース A にアクセスしようとするシナリオについて説明しています。
ただし、一部のビジーなアプリケーションでは、選択と更新の間、または複数の選択の間にデッドロックが発生することがよくあります。デッドロック トレース出力の細かい点のいくつかはかなり理解できないと思いますが、2 つの単一操作の間でデッドロックが発生する原因を理解したいと思います。確かに、選択に読み取りロックがある場合、更新は排他ロックを取得する前に待つ必要があり、その逆も同様ですか?
これは SQL Server 2005 で発生しており、違いがあるとは思いません。
oracle - Hibernate アプリケーションが読み取り専用でデータをロードしているときに Oracle がデッドロックする
Oracle デッドロック (org.hibernate.util.JDBCExceptionReporter - ORA-00060: リソースの待機中にデッドロックが検出されました) エラーが発生しています。別のプロセスが同じ行で更新を実行している間に、Hibernate を使用して読み取り専用操作を実行しているプロセスに問題があることが示唆されています。
問題の読み取り専用プロセスは、Hibernate と Spring を使用して構成されています。サービスのトランザクションを明示的に定義していません。それは理想的ではないかもしれませんが、保存/更新操作が実行されず、取得/ロードのみが実行されたときに、Hibernate が行の排他ロックを取得しようとする理由がわかりません。
だから私の質問は: Hibernate は、明示的なトランザクション管理が定義されていない場合、オブジェクトの「ロード」のみが実行された場合でも、行の読み取り/書き込みロックを取得しようとしますか? 保存/更新は実行されません。
データをロードしているサービスに関するトランザクションを定義し、transactionAttributes で明確に READONLY を指定すると、Hibernate が既存の行ロックを無視し、読み取り専用の目的でデータをロードする可能性はありますか?
以下にいくつかのコード例を示します。
レコードをロードするために、HibernateDaoTemplate を使用しています
このメソッドを呼び出すサービスの Spring 構成は次のとおりです。
実際のデッドロックは、PurchaseOrder をロードするための呼び出しによってロードされている PurchaseOrderItem レコードの 1 つで発生しています。
ロード中のレコードが別のプロセスによってロックされている場合、デッドロックが発生しますか? もしそうなら、以下のようなトランザクションラッパーを追加すると問題が解決しますか?
更新: データベース チームは、"読み取り専用" プロセスが実際にデータベースに自動的に書き込みを行っていることを示すように見えるトレース メッセージをサーバー上で確認しました。データベースから読み取っている正確な列に対して実行された「UPDATE」コマンドがログに記録されています。Hibernate は、これらのレコードをデータベースに自動的に書き戻しているようです (私たちが要求したわけではありませんが)。それはおそらくデッドロックがある理由を説明するでしょう。
これは、Session FLUSH などの原因である可能性がありますか? 解決策のように見えるのは、読み取り専用のトランザクションラッパーを使用することです...
c# - コードから発生したイベントを監視するソフトウェア
マウスクリックイベントに関連していると思われるコードブロック内で問題が発生していますが、コード内で正確なイベントをキャプチャできないようです。C#デバッガーを使用してコードをステップ実行しましたが、イベントの1つが終了すると、コードがロックされます。
私の投稿の目的は、私のプロセスを監視し、F11キーを押してコードがフリーズした後に発生するイベントを通知するソフトウェアがあるかどうかを尋ねることです。SysInternalsを試しましprocmon.exe
たが、どのイベントが発生しているのかわかりません。
multithreading - シャットダウン時のThreadPool、QueueUserWorkItem、およびDeadlock
ここで説明するようなスレッドプールを実装しました
非常に単純な実装で、正常に動作しますが、アプリケーションがシャットダウンしなくなりました。2つのワーカースレッド(および他の1つのスレッド、キューイングスレッド)が関数でスタックしているようです
QueueUserWorkItem(スレッドプールの実装で使用されるWinAPI関数)のヘルプエントリでIOの完了について何か読んだことを覚えていますが、正しく理解できませんでした。実行に時間がかかる可能性があり、既存のワーカースレッドが終了するのを待つのではなく、新しいワーカースレッドを作成する必要があるため、ワーカースレッドにWT_EXECUTELONGFUNCTIONを使用しました。ワーカースレッドに割り当てられたタスクの一部は、I/O処理を実行します。WT_EXECUTEINIOTHREADを使用しようとしましたが、役に立たないようです。
メインスレッドは、コールスタックが存在しないクリティカルセクションへのエントリを待機していることに注意してください。
私がここで間違っていることについて何か考えはありますか?よろしくお願いします。
database - データベースのデッドロック
データベースのデッドロックが発生する従来の理由の 1 つは、2 つのトランザクションが異なる順序でテーブルを挿入および更新している場合です。
たとえば、トランザクション A はテーブル A に挿入し、次にテーブル B に挿入します。
そして、トランザクション B がテーブル B に挿入され、その後に A が続きます。
このようなシナリオでは、常にデータベース デッドロックのリスクがあります (シリアライズ可能な分離レベルを使用していないと仮定します)。
私の質問は次のとおりです。
すべてのトランザクションが同じ順序で挿入および更新されるようにするために、設計でどのようなパターンに従いますか。私が読んでいた本には、テーブルの名前でステートメントを並べ替えることができるという提案がありました。このようなことや別のことをしたことがありますか - すべての挿入と更新が同じ順序になることを強制しますか?
レコードの削除についてはどうですか?削除は子テーブルから開始する必要があり、更新と挿入は親テーブルから開始する必要があります。これがデッドロックに陥らないようにするにはどうすればよいでしょうか?
java - 同期はJavaでどのように機能しますか
まず、サンプルを次に示します。
私が得られないのは、閉塞がどのように発生するかです。main関数は、それぞれが独自の弓を開始する2つのスレッドを開始します。
「同期」ブロックとは正確には何ですか?同じオブジェクトに対して同じ関数が実行されていますか(私が最初に思ったように)?同じクラスのすべてのオブジェクトに同じ関数?同じオブジェクトのすべての同期された関数?同じクラスのすべてのオブジェクトのすべての同期された関数?
ここで私を助けてください。
sql - 「アイデンティティ」なしで次のID番号を取得する最良の方法
レガシー データベースのテーブルにいくつかのレコードを挿入する必要がありますが、他の古いシステムで使用されているため、テーブルを変更することは解決策ではありません。
問題は、ターゲット テーブルに int 主キーがあるが ID 仕様がないことです。そのため、次に利用可能な ID を見つけて使用する必要があります。
ただし、問題が発生しないように、これを行っているときに他のアプリケーションがテーブルに挿入されないようにしたいと考えています。私はこれを試しました:
SQL Management Studio の 2 つの異なるウィンドウで、1 つのトランザクションが常にデッドロックの犠牲者として強制終了されます。
私もSET TRANSACTION ISOLATION LEVEL SERIALIZABLE
最初に試してみましたが、同じ結果でした...
次のIDを確実に取得して、他の誰か(または私!)が夢中になる危険を冒さずにそれを使用する方法についての良い提案はありますか?
これについて先に言及せずに申し訳ありませんが、これは SQL 2000 サーバーであるため、FOR UPDATE や OUTPUT などは使用できません。
更新:これは私のために働いた解決策です:
WAITFOR は、複数の接続を持ち、クエリを数回開始して同時実行を引き起こすためのものです。
回答してくれた Quassnoi と、貢献してくれた他のすべての人に感謝します! 素晴らしい!
c++ - MoveWindowデッドロック?
スレッド A にウィンドウがあり、ある時点で (wndproc でメッセージを受信した結果として) スレッド B でアクションをトリガーし、アクションが完了するのを待ちます (ある種の同期メカニズムを使用)。次に、スレッド B が を呼び出しMoveWindow()
て、子ウィンドウをスレッド A のウィンドウ (標準のテキスト ボックスなど) 内に移動します。この時点で、プログラムは何らかの理由でデッドロック状態になります。MoveWindow()
がスレッド A から呼び出されている場合、すべてが機能します。理由はありますか?