今回はMySQLの機能の一つであるトランザクション処理について、勉強した内容を紹介します。
概要については、以下の記事で紹介していますので、ご参考ください。
トランザクションの基本
トランザクションは、一連のデータベース操作をひとまとまりとして扱う機能です。
以下のACID特性を満たすことが求められます。
特性 | 説明 |
---|---|
原子性 (Atomicity) | トランザクション内のすべての操作が成功するか、全く実行されなかったかのどちらかになります。部分的な成功は許されません。 |
一貫性 (Consistency) | トランザクションが成功すると、データベースは一貫した状態に保たれます。トランザクション前後でデータの整合性が保たれます。 |
分離性 (Isolation) | 同時に実行されるトランザクションは互いに影響しません。トランザクションが完了するまで、他のトランザクションからの変更は見えません。 |
持続性 (Durability) | トランザクションがコミットされると、その結果は永続的に保存されます。システム障害が発生しても、コミットされたデータは失われません。 |
トランザクションの実行
MySQLでは、トランザクションを実行するために以下のコマンドを使用します。
項目 | 実行コマンド |
---|---|
トランザクションの開始 | START TRANSACTION; または BEGIN; |
データの操作 | INSERT、UPDATE、DELETEなどのSQL文を実行 |
トランザクションの終了 | コミット: トランザクションを確定し、変更を永続化します。COMMIT; または ロールバック: トランザクションを取り消し、変更を元に戻します。 ROLLBACK; |
実行例
実際にトランザクションを利用して、データ更新の実行例を紹介します。
環境は以下の通りです。
OS | CentOS Stream release 9 |
MySQL | 8.4.2 MySQL Community Server |
データベース名 | my_database |
テーブル名 | users |
テーブル:usersのデータは以下の通りです。
このうち、ユーザ:user01の年齢を35に変更する処理をトランザクション処理で実行します。
mysql> select * from users;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | user01 | 30 |
| 2 | user02 | 25 |
+----+--------+------+
2 rows in set (0.00 sec)
mysql>
トランザクションの開始
最初にトランザクションを開始します。
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.01 sec)
mysql>
データ更新
次にユーザ:user01の年齢を35に変更するSQL文を実行します。
実行後のSELECT文で、値が変更されていることを確認できました。
mysql> UPDATE users SET age = 35 WHERE name = 'user01';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from users;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | user01 | 35 |
| 2 | user02 | 25 |
+----+--------+------+
2 rows in set (0.00 sec)
mysql>
変更の確定または取り消し
変更を確定する場合
変更の確定する場合は、COMMITコマンドを実行します。
実行後のSELECT文の情報から変更が確定され、値が変更されていることをが確認できます。
mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from users;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | user01 | 35 |
| 2 | user02 | 25 |
+----+--------+------+
2 rows in set (0.00 sec)
mysql>
変更を取り消す場合
変更の取り消す場合は、ROLLBACKコマンドを実行します。
実行後のSELECT文の情報から変更が取り消され、値が変更前の状態に戻っていることをが確認できます。
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from users;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | user01 | 30 |
| 2 | user02 | 25 |
+----+--------+------+
2 rows in set (0.01 sec)
mysql>
ストレージエンジンの選択
ストレージエンジンとは
MySQLのストレージエンジンは、データの保存、取得、管理の方法を決定する重要なコンポーネントです。
ストレージエンジンは、テーブルごとに異なるものを選択でき、各エンジンには特定の機能や特性があります。
トランザクション処理との関係
MySQLのストレージエンジンは、トランザクションをサポートするものとサポートしないものがあります。
代表的なストレージエンジンを例にとって紹介します。
- InnoDB: ACIDに準拠したトランザクションをサポートしており、デフォルトのストレージエンジンです。
- MyISAM: トランザクションをサポートしていません。
トランザクションが必要な場合は、InnoDBを使用することが推奨されます。
トランザクションの分離レベル
分離レベルとは
分離レベルとは、トランザクションが他のトランザクションからどのように影響を受けるかを制御する設定です。
分離レベルは、データの整合性と同時実行性のバランスを取るために重要です。
例えば、他のトランザクションで更新されているデータを、別のトランザクションで読み取る処理を実施する場合、データが更新前のデータで読み込んで良いか、更新後のデータを読み込む必要があるかを指定するようなイメージです。
分離レベルの種類
主な分離レベルは以下の4つです。
分離レベル | 説明 | メリット | デメリット |
---|---|---|---|
READ UNCOMMITTED | 他のトランザクションが未コミットのデータを読み取ることができます。 | 最も高い同時実行性を提供します。 | ダーティリード(トランザクションが未コミットのデータを読み取ること)が発生する可能性があり、データの整合性が保証されません。 |
READ COMMITTED | 他のトランザクションがコミットしたデータのみを読み取ることができます。 | ダーティリードを防ぎます。 | 反復可能読み取り(同じクエリを複数回実行した場合に異なる結果が得られること)が発生する可能性があります。 |
REPEATABLE READ | トランザクション内で同じクエリを実行すると、常に同じ結果が得られます。 | 反復可能読み取りを保証し、データの整合性を高めます。 | ファントムリード(新しい行が追加されることによって、クエリの結果が変わること)が発生する可能性があります。 |
SERIALIZABLE | 最も厳格な分離レベルで、トランザクションが直列に実行されるように見えます。 | データの整合性が最も高く、すべてのトランザクションが他のトランザクションの影響を受けません。 | 同時実行性が低下し、パフォーマンスに影響を与える可能性があります。 |
分離レベルの確認・設定
分離レベルは以下のコマンドで確認・設定できます。
確認
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;
設定
SET SESSION TRANSACTION ISOLATION LEVEL [レベル]; ※現在のセッションの分離レベルを変更
SET GLOBAL TRANSACTION ISOLATION LEVEL [レベル]; ※全ての新しいセッションに対して分離レベルを変更
実行例
実際に実行した結果は以下の通りです。
バージョン:8.4.2の場合、デフォルトはセッション単位、グローバル単位どちらも「REPEATABLE-READ」が設定されています。
このうちセッション単位の分離レベルを「READ UNCOMMITTED」に変更します。
実行結果から、セッションの分離レベルが正常に変更されていることが確認できました。
mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;
+--------------------------------+-------------------------+
| @@GLOBAL.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| REPEATABLE-READ | REPEATABLE-READ |
+--------------------------------+-------------------------+
1 row in set (0.01 sec)
mysql>
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;
+--------------------------------+-------------------------+
| @@GLOBAL.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| REPEATABLE-READ | READ-UNCOMMITTED |
+--------------------------------+-------------------------+
1 row in set (0.00 sec)
mysql>
まとめ
今回はMySQLの機能の一つであるトランザクション処理について、紹介しました。
MySQLのトランザクション処理は、データの整合性と一貫性を保つための重要な機能であり、適切に利用することで信頼性の高いデータベースシステムを構築できます。
ご参考になれば、幸いです。
以上になります。ありがとうございました。
参考
https://ja.wikipedia.org/wiki/MySQL
https://www.wakuwakubank.com/posts/200-mysql-transaction
https://dev.mysql.com/doc/refman/8.0/ja/converting-tables-to-innodb.html
https://qiita.com/song_ss/items/38e514b05e9dabae3bdb
https://dev.mysql.com/doc/refman/8.0/ja/commit.html
コメント