MySQL トランザクション同時実行問題の解決

MySQL トランザクション同時実行問題の解決

開発中にこのような問題に遭遇しました

ビデオ視聴記録が 100 に更新されると、視聴されたことを意味し、後続のリクエストがあった場合は更新されません。

消す:

その結果、内部の多くのデータに問題が生じます。

次のような状況が、

最初のリクエスト トランザクションは実行中であり、コミットされていません (ローカルで再現することが難しい場合があるため、この効果を実現するために、最初のレコードを処理するときにプログラム内で手動で数秒間スリープします)

2 番目のリクエスト トランザクションの実行が開始されました。この時点で、見つかった履歴の最大値は 100 ではないため、更新されます。

解決策をオンラインで調べました:

悲観的ロック

直接ロック行レコード

これをローカルでテストしたところ、本当にうまくいきました。1 つのトランザクションは開始されますが終了せず、2 番目のトランザクションは待機します。ただし、システムの同時実行性により、ブロッキング状態が発生します。私はあえてそれを考慮しないので、この方法を記録するだけです。

手動シミュレーション:

最初のトランザクションを実行します。

-- ビデオ 100 開始;

`biz_coursestudyhistory` から * を選択 WHERE sid = 5777166;

biz_coursestudyhistory を更新し、studyStatus を 100、versionNO を versionNO+1 に設定します (sid が 1 で、versionNO が 0 の場合)。

-- commit ; 最初に実行せず、最初に注釈を付け、上記のみを実行する

次に、2 番目のトランザクションを実行します。

始める;
 
biz_coursestudyhistory を更新し、studyStatus を 90、versionNO を versionNO+1 に設定します (sid が 1 で、versionNO が 0 の場合)。
 
SELECT * FROM `biz_coursestudyhistory` WHERE sid = 1 FOR UPDATE;
 
専念;

あなたは成功できず、常に待機状態にあることに気づくでしょう。

ロックを表示

確かにロックされています。ここでは、最初のトランザクションのコミットが実行されている限り、2 番目のトランザクションが実行されます。

このことから、行ロックは理想的なデータ統合状態を直接実現できることがわかります。1 つのトランザクションが変更されると、他の操作は実行できなくなります。これは、銀行などのセキュリティ プロジェクトに適していると感じています。

楽観的ロック:

これはより単純で、ブロックを引き起こしません

方法はバージョン番号を追加することです

var maxver = select max(version) from table

更新するには、

update table set studystatus = xxx,version = version +1 where id =1 and version = maxver

書かれた言葉

テーブル (contentStudyID、courseWareID、studyStatus、studyTime、endTime) に INSERT します。
SELECT 27047358,3163,100,333,NOW() FROM デュアル WHERE NOT EXISTS (SELECT 1 FROM テーブル WHERE contentStudyID =27047358 AND
コースウェアID = 3163
 )

このように、更新時や書き込み時に、ライブラリ内のデータが存在するかどうかを直接判断できます。存在しない場合は、他のスレッドによって使用されます。

この記述スタイルに変更した後、マルチスレッド テストに jmeter を使用すると、当初は複数のレコードの更新は成功しましたが、現在は 1 つのレコードのみが正常に実行され、残りは失敗します。

最初に複数のレコードを挿入することから、後で1つのデータのみを挿入することまで

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL トランザクション機能を使用して同時かつ安全な自動増分 ID を実装する例
  • PHP+MySQL の高同時ロックトランザクション処理問題の解決方法
  • MySQL の繰り返し読み取りレベルでファントム読み取りを解決できますか?
  • MySQLがファントムリードを解決する方法の詳細な説明
  • MySQL ファントムリードとその排除方法の詳細な説明
  • MySQL シリーズ 10 同時実行制御を実装するための MySQL トランザクション分離
  • MySQL のファントムリード問題を解決する方法
  • mysql+mybatisはストアドプロシージャ+トランザクション+複数同時シリアル番号取得を実装します
  • Mysql トランザクションにおける同時ダーティ リード + 非反復リード + ファントム リードの詳細な説明

<<:  nginx を使用して http を https に変換するサンプルコード

>>:  Nginx コンパイル済み nginx - 新しいモジュールを追加

推薦する

Vue3.0プロジェクトの構築と利用プロセス

目次1. プロジェクト構築2: ディレクトリ構造3: コンポジションAPI 4: 基本的な使い方:最...

Docker ベースの ELK ログ システムを構築する方法

背景要件:ビジネスがどんどん大きくなると、サーバーの数も増え、さまざまなアクセスログ、アプリケーショ...

Linux で nginx を起動および再起動する方法

Nginx (エンジン x) は、IMAP/POP3/SMTP サービスも提供する高性能 HTTP ...

Mysql WorkBench のインストールと設定のグラフィックチュートリアル

この記事では、Mysql WorkBenchのインストールと設定のグラフィックチュートリアルを参考ま...

MySQL の同時実行性の問題と解決策の分析

目次1. 背景2. テーブルロックによるクエリの遅延3. オンラインでテーブル構造を変更するとどのよ...

Vue の DOM の非同期更新の簡単な分析

目次Vue が DOM を非同期更新する原理1 実際の DOM 要素を取得できるのはいつですか? 2...

JavaScript ツールチェーンの不完全なガイド

目次概要静的型チェックコードスタイルチェック(Linter)パッケージマネージャーモジュールローダー...

Prometheusコンテナのデプロイメントのための実用的なソリューション

環境ホスト名IPアドレス仕えるプロメテウス192.168.237.137プロメテウス、グラファナノー...

HTML/CSS におけるフロートの使用例の詳細

1. floatの基本的な使用例1. まず 2 つの div ボックスを作成し、高さ、幅、背景色を設...

div の幅が width:100% に設定されていて、パディングまたはマージンが親要素を超えてしまう問題の解決方法

序文この記事では、div の幅を 100% に設定し、親要素を超えてパディングまたはマージンを設定す...

React Fragment の紹介と詳しい使い方

目次序文フラグメントの動機React Fragment の紹介と使用<React.Fragme...

MySQL データベース分離レベルと MVCC の詳細な説明

目次1. 分離レベルコミットされていない読み取りREAD COMMITED (コミット読み取り/非反...

Linuxの運用と保守の基本プロセス管理と環境構成分析

目次1. プロセスの基本的な概要2. プロセスの構成要素3. プロセス環境4. プロセスステータス5...

CSS で中空マスク レイヤーを実装するサンプル コード

この記事の内容: ページ中空マスクレイヤー、ページ中空マスクガイドレイヤー、画像中空マスク通常のマス...

Web デザインの経験: 独善的な Web デザイナー

1. ゴミかクラシックか? Web テクノロジーは急速に更新されており、Web サイトのインターフェ...