資格のあるプログラマはあなたの基本的な知識を閉じ込めなければなりません

デッドロック、私は誰もが見知らぬ人ではないと思います。簡単に言えば、両方のパーティーが自分のボウルを食べて、お互いのボウルを見つめているため、両方のパーティーがすべてを食べることは不可能です。
たとえば、Aがマーチャントでモノを購入すると、一連の非常に複雑なデータベース操作が完了します。これを次の2つの操作に簡略化できます。Aのアカウント金額は-50で、その後マーチャントの金額は50です。同時に、マーチャントP2が偶然にそのような操作を完了し、Aからの払い戻しを検討したため、マーチャントの金額が100減り、Aアカウントの金額が100増加しました。したがって、前の操作ではAのアカウントを変更する行ロックを取得し、Aのアカウントを50減らしましたが、トランザクションは完了しておらず、50をマーチャントアカウントに追加する必要があります。後者の操作では、商人の行ロックが取得され、商人のアカウントから100が差し引かれ、トランザクションも完了しませんでした。Aの行ロックが取得されるまで待つ必要があり、その後、アカウントの金額が100増加します。
このようにして、前のトランザクションはユーザーの行ロックを取得してマーチャントのロックを待機し、後者のトランザクションはマーチャントのロックを取得してユーザーのロックを待機します。どちらのユーザーも満足できず、トランザクションを完了できず、デッドロックが形成されます。では、Mysqlがデッドロックに遭遇するとどうなりますか?
MySQLは、このようなinnodb_lock_wait_timeoutによって構成されます。つまり、両サイドが静止できない場合は、今回の間に競合が発生しないように、この時間の後、両サイドが手放して再試行します。ただし、この時間が長すぎると、ユーザーが数十秒待ってから再試行することはできません。この時間を短すぎると、誤っている可能性があります。元のステートメントは2秒間実行されますその結果、タイムアウト期間は1秒に設定され、最後のトランザクションはロールバックされます。
MySQLには、デッドロックをチェックする別の関数innodb_deadlock_detectも用意されています。このスイッチをオンにすると、ステートメントを実行してロックを取得できない場合は常に、他のスレッドをトラバースしてデッドロックが発生したかどうかを確認します。 。通常の状況では、このスイッチをオンにすることはお勧めしません。たとえば、同じ行を同時に更新するスレッドが1000ある場合、他の999のスレッドはロックを取得できないため、各トランザクションは実際には1つの処理しか実行しません。互いにトラバースして、デッドロックが形成され、大きなオーバーヘッドが発生していないかどうかを確認します。
では、このデッドロックが発生する状況をどのように回避すればよいでしょうか。ビジネス設計でデッドロックが発生する可能性を回避するために最善を尽くすべきだと思います。まず、上記の例では不当な設計を回避する必要があります。ユーザーの金額を最初に操作し、次に販売者の金額を操作するように支払いと払い戻しの両方を設計しないのはなぜですか?また、同時実行性が高いことについても述べましたステートメントはトランザクションの後に配置されます。これは、トランザクションの実行効率を高めるのに役立ちます。同時に、デッドロックの可能性を減らし、1石で2羽の鳥を殺します。
第2に、重要度が低い場合は、同時実行数を制限する必要があります。そうしないと、顧客はビジネスの特定の遅延を受け入れることができ、制限付きの同時実行またはシリアル化を使用して実行できます。たとえば、WeiboファンやWeChatパブリックアカウントサブスクリプションのように、シリアル化を使用してから統計のためにマージできます。

おすすめ

転載: www.cnblogs.com/jiuq521/p/12695367.html