MySQLのネストされたトランザクションで発生する問題

MySQLのネストされたトランザクションで発生する問題

MySQL はネストされたトランザクションをサポートしていますが、それを実行する人は多くありません... 少し前に、MySQL のネストされたトランザクションの必要性について議論している外国人を見ました。 とても面白いですね。このネストされた奇妙な使用法が必要なシナリオはあるのでしょうか? 元 DBA の同僚と話をしたところ、MySQL のネストされたトランザクションはどのようなシナリオでも使用すべきではないことがわかりました。

では、MySQL のネストされたトランザクションを使用するとどのような問題が発生するのでしょうか?

mysql> ceshi から * を選択します。 
+------+ 
| いいえ | 
+------+ 
| 1 | 
+------+ 
セット内の 1 行 (0.00 秒) 
 
mysql> トランザクションを開始します。 
クエリは正常、影響を受けた行は 0 行 (0.00 秒) 
 
mysql> ceshi 値に挿入します(2); 
クエリは正常、1 行が影響を受けました (0.00 秒) 
 
mysql> トランザクションを開始します。 
クエリは正常、影響を受けた行は 0 行 (0.00 秒) 
 
mysql> ceshi 値に挿入します(3); 
クエリは正常、1 行が影響を受けました (0.00 秒) 
 
mysql> コミット; 
クエリは正常、影響を受けた行は 0 行 (0.00 秒) 
 
mysql> ロールバック; 
クエリは正常、影響を受けた行は 0 行 (0.00 秒) 


最後にロールバックしたのに、データには 1 2 3 と表示されました。当初、トランザクションがネストされた状態だったのに、最後にロールバックしたと誰もが考えていました。実際、私たちが期待する結果は、サブトランザクションが正常に実行され、外側のトランザクションの失敗がロールバックされることです。 しかし、そうではありません。最終結果は 1 2 3 です。

+-----+ 
| いいえ | 
+-----+ 
| 1 | 
| 2 | 
| 3 | 
+-----+ 

SQL インタープリターがトランザクションの開始を検出すると、コミットがトリガーされます... !!!

begin_1 sql_1 begin_2 sql_2 sql_3 commit_1 rollback_1 .

begin_2 を実行すると、sql_1 はすでにコミットされています。commit_1 を実行すると、sql_2 と sql_3 はすでにコミットされています。この時点で、ロールバックすると無駄になります...すでにコミットされているため、何をロールバックできますか...

前述したように、アーキテクチャではネストされたトランザクションを使用する人はほとんどいませんが、誤ってネストされることもあります。 Python プロジェクトを例に挙げてみましょう。まず、デコレータを使用してトランザクション パッケージを実装します。次に、データ処理関数 def a() と def b() がトランザクションにラップされます。これらはすべて単一のトランザクションであるため、単に a または b を使用するかどうかは問題ではありません。 ロジック内で a が b を呼び出すと、何が起こりますか? はい、トランザクションはネストされています...これはほとんどのビジネス開発者が遭遇する問題だと思います。

では、このリスクを回避するにはどうすればよいでしょうか? ロックすることができます... サブトランザクションを作成する前に、グローバル ロックを設定し、ロック ステータスを確認します...

Flask フレームワークを使用している場合は、flask g グローバル変数を使用できます。

Django フレームワークの場合は、スレッドローカルを使用してグローバル変数を使用できます。

tornado や gevent などの非同期 IO アーキテクチャの場合は、fd を使用してコルーチン変数を関連付けることができます。

@デコレータ
def with_transaction(f, *args, **kwargs):
 
  db = connection.get_db_by_table("*")
  試す:
    db.begin()
    ret = f(*args, **kwargs)
    コミット()
  を除外する:
    ロールバック()
    上げる
  リターン ret
 
 
@トランザクションあり
def hid(self):
  '''注文がアプリに表示されません'''
  self.status が OrderStatus.allow_deletion_statuses() にない場合:
    OrderStatusChangeNotAllowed(self.status, OrderStatus.deleted) を発生させます。
...
 
 
@トランザクションあり
def change_receipt_info(自分、住所、名前、電話番号):
  地域 = Region.get_by_address(アドレス)
  ...

次のステートメントを実行すると、トランザクションは強制的にコミットされます。もちろん、ここでの前提は autocommit = True です。

関数の変更  
手順の変更  
テーブルの変更  
始める  
データベースの作成  
関数を作成する  
インデックスの作成  
手順の作成  
テーブルの作成  
データベースの削除  
ドロップ機能  
インデックスを削除  
ドロップ手順  
テーブルを削除  
テーブルのロックを解除  
マスターデータをロード  
ロックテーブル  
テーブル名の変更  
テーブルを切り捨てる  
AUTOCOMMIT=1 を設定します  
取引を開始  

以下もご興味があるかもしれません:
  • PHP で MySQL ネストトランザクションを実装するための 2 つのソリューション
  • MySQL ストアド プロシージャの例 (トランザクション、出力パラメータ、ネストされた呼び出しを含む)

<<:  Vueのv-onパラメータの問題についてお話しましょう

>>:  Eclipse/Tomcat でホットデプロイメントとホットスタートを実装する方法

推薦する

docker イメージのプル速度が遅い問題の解決策

現在、Docker には中国向けの公式ミラーがあります。詳細については、https://www.do...

MySQLインデックスとは何ですか?わからない場合は聞いてください

目次概要二分木からB+木へクラスター化インデックス非クラスター化インデックスジョイントインデックスと...

背景位置パーセンテージ原則の詳細な説明

今日、誰かがコードを調整するのを手伝っていたとき、次のようなスタイルを見つけました。 背景位置: 5...

SWFObjectを使用すると、HTMLにFlashを挿入する際のブラウザ互換性の問題を完全に解決できます。

一緒に学びましょう1. 伝統的な方法コードをコピーコードは次のとおりです。 <object c...

Nginx 逆生成 Mogilefs 分散ストレージ例の詳細な説明

1. 分散ストレージシステムの概要情報技術の継続的な発展により、利便性がもたらされる一方で、データ量...

Docker+DockerCompose を使用して Web アプリケーションをカプセル化する方法

目次テクノロジースタックバックエンドビルドAPIフロントエンドウェブ構築ゲートウェイ建設ゲートウェイ...

MySQLを閉じることができない問題を解決する方法

mysql が閉じない場合の解決策:コンピュータのタスクバーを右クリックしてタスクマネージャーを開き...

8 JSのreduce使用例とreduce操作方法

reduceメソッドは配列の反復メソッドです。 mapやfilterとは異なり、 reduceメソッ...

Vue におけるキープアライブ マルチレベル ルーティング キャッシュの問題

目次1. 問題の説明2. 原因分析3. 解決策4. 処理1. 問題の説明調整センターでは、最後の 2...

Html/Css (初心者が最初に読むべきガイド)

1. Web標準の意味を理解する - なぜWeb標準を採用するのか***** コンテンツとスタイル...

Tudou.com フロントエンドの概要

1. 分業とプロセス<br />Tudou.comでは、プロジェクト開発が中核であり、誰...

Hbase 入門

1. HBaseの概要1.1 HBaseとはHBase は、高い信頼性、高いパフォーマンス、列ストレ...

MySQL スケジュールタスクの実装と使用例

この記事では、例を使用して、MySQL スケジュール タスクの実装と使用方法を説明します。ご参考まで...

UbuntuはSSHサービスのリモートログイン操作を開始します

ssh-secure シェルは、安全なリモート ログインを提供します。組み込みシステムを開発し、Li...