MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

セッションがDBAによって強制終了された場合、実行中のMySQLトランザクションはどうなる?

トランザクションの実行中にセッションが強制終了(KILL)された場合、MySQLはそのトランザクションを自動的にロールバックして終了させます。これは「暗黙的ロールバック(implicit rollback)」と呼ばれる動作です。

つまり、ロールバックが発生した時点で、そのトランザクション内で行われたすべてのデータベースへの変更は取り消され、テーブルはトランザクション開始前の状態に戻ります。

動作を確認する具体例

ここでは、実際のコマンド操作を通じてこの挙動を確認してみましょう。まず、次のようなデータが登録されたテーブル「marks」を用意します。

mysql> Select * from marks;
+------+---------+-----------+-------+
| Id   | Name    | Subject   | Marks |
+------+---------+-----------+-------+
|    1 | Aarav   | Maths     |    50 |
|    1 | Harshit | Maths     |    55 |
|    3 | Gaurav  | Comp      |    69 |
|    4 | Rahul   | History   |    40 |
|    5 | Yashraj | English   |    48 |
|    6 | Manak   | History   |    70 |
+------+---------+-----------+-------+
6 rows in set (0.00 sec)

1. トランザクションを開始して行を削除する

新しいトランザクションを開始し、「marks」テーブルから1行削除します。

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> Delete from marks where id = 4;
Query OK, 1 row affected (0.00 sec)

この時点ではまだCOMMITもROLLBACKも実行していないため、削除処理は確定していません。

2. 別のセッションからプロセス一覧を確認する

COMMITまたはROLLBACKを実行する前に、別のウィンドウでMySQLの別インスタンスを起動し、SHOW PROCESSLISTコマンドを実行して現在の接続状況を確認します。

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
      Id: 2
    User: root
    Host: localhost:49303
      db: query
Command: Sleep
    Time: 22
   State:
    Info: NULL
*************************** 2. row ***************************
      Id: 3
    User: root
    Host: localhost:49350
      db: NULL
Command: Query
    Time: 0
   State: NULL
    Info: show processlist
2 rows in set (0.00 sec)

トランザクションを実行中のセッションは、Id「2」として表示されています。

3. KILLコマンドでセッションを強制終了する

次に、KILLコマンドを使ってこのセッションを強制終了します。

mysql> KILL 2;
Query OK, 0 rows affected (0.00 sec)

4. 元のセッションでCOMMITを試みる

元のトランザクションのウィンドウに戻り、COMMITコマンドを実行してみます。

mysql> COMMIT;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 4
Current database: query
Query OK, 0 rows affected (1.01 sec)

「ERROR 2006 (HY000): MySQL server has gone away」というエラーが表示され、接続が切断されたことがわかります。その後、自動的に再接続が試みられ、新しい接続ID「4」が割り当てられています。

結果:変更はロールバックされている

このKILLコマンドによるセッションの強制終了により、MySQLは実行中のトランザクション内で行われた変更を強制的にロールバックしました。実際にテーブルを確認すると、削除したはずの行が元通りに存在していることがわかります。

mysql> Select * from marks;
+------+---------+-----------+-------+
| Id   | Name    | Subject   | Marks |
+------+---------+-----------+-------+
|    1 | Aarav   | Maths     |    50 |
|    1 | Harshit | Maths     |    55 |
|    3 | Gaurav  | Comp      |    69 |
|    4 | Rahul   | History   |    40 |
|    5 | Yashraj | English   |    48 |
|    6 | Manak   | History   |    70 |
+------+---------+-----------+-------+
6 rows in set (0.00 sec)

このように、id = 4 の行(Rahulのレコード)は削除されておらず、テーブルには6行すべてが残っています。

まとめ

  • セッションがKILLコマンドなどで強制終了されると、実行中のトランザクションはMySQLによって自動的にロールバックされる。
  • これを「暗黙的ロールバック」と呼び、トランザクション内の未確定の変更はすべて破棄される。
  • この仕組みにより、処理の途中で接続が切れてもデータベースの一貫性が保たれる。

DBAがメンテナンス作業などでセッションを強制終了するケースは珍しくありませんが、トランザクションのACID特性(原子性)によって、中途半端な状態でデータが確定することはないため、安心して運用できます。

  1. MySQLにおけるEXCEPTの代替方法:NOT IN演算子を使った差集合の取得手順を解説

    MySQLにはEXCEPT句が存在しない? SQL標準には、2つの結果セットの差を求めるためのEXCEPT演算子があります。しかし、従来のMySQLではEXCEPTを利用できないため、代わりにNOT IN演算子を使用するのが一般的な方法です。 この記事では、実際にテーブルを作成しながら、NOT IN演算子を使ってEXCEPTと同じ結果(差集合)を取得する手順を詳しく解説します。 サンプルテーブルの作成 まず、比較元となる1つ目のテーブルを作成します。 mysql> create table DemoTable ( Number1 int ); Query OK,

  2. MySQLのエイリアスでASキーワードは省略できる?使い方を実例付きで解説

    MySQLでは、カラムにエイリアス(別名)を付ける際、ASキーワードを明示的に書く方法とASを省略する方法の2通りがあります。どちらの書き方でも同じ結果が得られますが、この記事では実際のSQL文の例を通して、それぞれの使い方と実行結果を詳しく解説します。準備:サンプルテーブルの作成まず、以下のコマンドでテーブルを作成します。mysql> create table DemoTable     (     Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,  &nbs