セッションが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特性(原子性)によって、中途半端な状態でデータが確定することはないため、安心して運用できます。
-
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,
-
MySQLのエイリアスでASキーワードは省略できる?使い方を実例付きで解説
MySQLでは、カラムにエイリアス(別名)を付ける際、ASキーワードを明示的に書く方法とASを省略する方法の2通りがあります。どちらの書き方でも同じ結果が得られますが、この記事では実際のSQL文の例を通して、それぞれの使い方と実行結果を詳しく解説します。準備:サンプルテーブルの作成まず、以下のコマンドでテーブルを作成します。mysql> create table DemoTable ( Id int NOT NULL AUTO_INCREMENT PRIMARY KEY, &nbs