WEBデザイン・開発講義WEB Design&Development Lecture
「MySQL」のトランザクション処理とSQLコマンド
「MySQL」のトランザクション処理及びSQL文法とコマンド操作
『MySQL』のDBサーバとしてトランザクション処理をする場合、ロック制御、分離レベル、データベースの選択、SQLコマンドの利用方法を理解する必要があります。
SQLコマンドの操作で、トランザクション開始と終了や「セーブポイント」を設けて処理中にエラーが発生した場合に元に戻す処理「ロールバック」する方法などを実践します。
分離レベルと読み方「ダーティリード」「ノンリピータブルリード」「ファントムリード」の関連でのSQLコマンドの使い方の相違点を理解します。
「MySQL」のトランザクション処理とデータベース作成、SQLコマンド操作の実践
「MySQL」のトランザクション処理※画像クリックで拡大表示(リンク)
トランザクション処理とは
複数の作業を連結した処理単位を「トランザクション 」といい、トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のどちらかの保証が必要です。
MySQLのデータベースエンジン比較と選択
エンジン MyISAM InnoDB NDB
最大格納容量 256TB 64TB 384EB
トランザクション X 〇 〇
ロック精度 テーブル 行 行
MVCC X 〇 〇
クラスタDB X X 〇
インデックス特徴 前文検索 クラスタ化 ハッシュ
特徴 インデックスキーをコントロール ACIDトランザクション処理 クラスタ化データベースサポート
トランザクション処理には、デフォルトの「InnoDB 」データベース・エンジンが最適です。
データベース・エンジンを確認するには、 「show table status 」のコマンド入力で表示されます。
トランザクション処理データベース作成とSQLの修飾句コマンド操作
トランザクション処理の「ec_trans」データベース作成
トランザクション処理の理解する上で、事例として下記に「商品トランザクション処理のER図」を示します。
「SQL」コマンド「SELECT」文の修飾句の操作
「注文明細トランザクション」のテーブルを利用して、「SELECT」文の修飾句 を理解し、SQLコマンドの操作を実践します。
【 注文明細トランザクション:「SELECT」文の修飾句 】
修飾句 説明とコマンド例
DISTINCT 重複する行を取り除いて表示する
sql> select distinct order_number, order_date, customer_id from order_detail;
WHERE 条件を指定する
sql> select order_number,order_date from order_detail where order_date='2014-05-06';
GROUP BY データをグループ化する
sql> select order_number, count(*), customer_id from order_detail group by order_number;
HAVING グループ化されたものに条件を設定する
sql> select order_number, count(*) as item_num, customer_id from order_detail group by order_number having item_num>1;
ORDER BY 結果の並び順を指定する
sql> select order_number, sum(quantity * order_price) as amount,order_date from order_detail group by order_number order by amount desc ;
LIMIT 指定した部分だけを結果として取得する
sql> select order_number, sum(quantity * order_price) as amount,order_date from order_detail group by order_number order by amount desc limit 5;
注文明細の「SELECT」修飾句のコマンド操作例: 「orderDetail_select_operation.sql」のダウンロード 理解を深めるため、操作事例を参考にして、コマンド操作を実践してください。
「SELECT」文の修飾句操作の実践(ビデオ表示)
「order_detail」テーブルの修飾句の操作:1 (9分40秒)
「order_detail」テーブルの修飾句の操作:2 (7分36秒)
トランザクション処理のコマンド操作
MySQLのトランザクション処理のSQLコマンド
SQLコマンド 内容
SET TRANSACTION ISOLATION LEBEL {xxxx} トランザクション分離レベルの設定{xxxx} の4つのモード指定(上記参照)が可能
START TRANSACTION トランザクション処理の開始(ロックの初期化)
BEGIN
COMMIT トランザクション処理の確定
SET AUTOCOMMIT = {0 | 1} AUTO COMMITモードのON「1 」とOFF「0 」の設定
SAVEPOINT 名前 セーブポイントの「名前」を設定
ROLLBACK TO SAVEPOINT 名前 「名前」のセーブポイントへ ロールバックをする
SELECT ... FOR UPDATE 行ロックをする(手動ロック)
LOCK TABLES と UNLOCK TABLES テーブル (ビュー以外) をロック と ロック全てを解放※ テーブルの更新処理で、トランザクションをエミュレートやスピードアップの際に利用(手動ロック)
トランザクション開始と終了コマンド操作
MySQLコマンドプロンプトの初期操作で、「er_trans 」のデータベースを選択して、どのようなテーブルがあるかを確認。
トランザクション開始とロールバック操作
トランザクション開始「START TRANSACTION 」文を実行し、「products」テーブルの「product_id」カラムが 'p140500004'であるレコードに対して、「order_quant」カラムの値を「99」に更新するUPDATE文を実行する。その後「ROLLBACK 」文でUPDATE文の実行内容が無効であることを確認できます。
トランザクション開始とコミット操作
トランザクション開始「BEGIN 」文を実行し、「products」テーブルの「product_id」カラムが 'p140500004'であるレコードに対して、「order_quant」カラムの値を「99」に更新するUPDATE文を実行する。その後「COMMIT 」文でUPDATE文の実行内容が有効となったことを確認できます。
トランザクション開始とセーブポイント操作
トランザクション開始「BEGIN 」文を実行し、「ship_detail」テーブルに1件のデータ:伝票番号「t14050008」を挿入します。その後、セーブポイント「SAVEPOINT tr01 」を設定します。1件のデータ:伝票番号「t14050009」を挿入し、伝票番号「t14050004」の数量を「9」に変更更新して、「ship_detail」テーブル内容を確認し、セーブポイントまで戻る「ROLLBACK tr01 」文を実行。
指定された名前のセーブポイントの位置の処理までにロールバックした内容「セーブポイント以降の挿入と更新処理が無効であること 」の確認ができます。
続けて「ロールバック」を実行するとトランザクション開始「BEGIN」文の位置までの処理の伝票番号「t14050008」の挿入が無効となっていることが確認できます。
トランザクション処理のコマンド操作(ビデオ表示)
「products」テーブルのトランザクション開始と終了コマンド操作 (4分19秒)
「ship_detail」テーブルのセーブポイントとロールバックのコマンド操作 (6分47秒)
トランザクション処理分離レベルのコマンド操作
トランザクション開始前に「SET TRANSACTION ISOLATION LEVEL xxx」の分離レベルを設定します。
今回の操作は、2人のユーザが同じテーブルを同時操作する前提のコマンド操作です。
ユーザ [A] の操作 ユーザ [B] の操作
REPEATABLE READの例
[A] SET AUTOCOMMIT=0; BEGIN; SELECT * FROM tbl WHERE id=2;※ 「id=2」の「clmn」が'xx' を表示
[B] SET AUTOCOMMIT=0; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ ; BEGIN; SELECT * FROM tbl WHERE id=2;※ 「id=2」の「clmn」が'xx' を表示
[A] UPDATE tbl SET clmn='aaa' WHERE id=2; SELECT * FROM tbl WHERE id=2;※ UPDATE文実行で、「id=2」の「clmn」が'aaa' を表示
[B] SELECT * FROM tbl WHERE id=2;※ 「id=2」の「clmn」が'xx' を表示(値が変わらない )
[A] INSERT INTO tbl VALUES(5,'zzz',..); SELECT * FROM tbl;※ INSERT文実行で、追加した「id=5」の「clmn」'zzz' も表示
[B] SELECT * FROM tbl WHERE id=2;※ 「id=2」の「clmn」が'xx' を表示「id=5」の追加分は表示されない(値が変わらない)
[A] COMMIT; SELECT * FROM tbl WHERE id=2;※ UPDATE,INSERT文の実行結果の反映した内容を表示、「id=2」の「clmn」が'aaa' 、「id=5」の「clmn」が'zzz'
[B] SELECT * FROM tbl WHERE id=2;※ 「id=2」の「clmn」が'xx' を表示、「id=5」の追加分は表示されない(同一トランザクション内で値が変わらない ) →「InnoDB」のため、ファントムリードが起きない
SERIALIZABLEの例
[A] SET AUTOCOMMIT=0; BEGIN; SELECT * FROM tbl;※ 「id=2」の「clmn」が'xx' を表示
[B] SET AUTOCOMMIT=0; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE ; BEGIN; SELECT * FROM tbl;※ 「id=2」の「clmn」が'xx' を表示
[A] UPDATE tbl SET clmn='aaa' WHERE id=2;※ ロック状態のため、[B] の実行結果待ち
[B] ROLLBACK;※ Transaction終了し、共有ロックを解放
[A] ※ ロックが外れたのでUPDATEが実行される SELECT * FROM tbl;※ UPDATE文の実行で、「id=2」の「clmn」が'aaa' を表示
トランザクション分離レベルのコマンド操作(ビデオ表示)
トランザクション分離レベルの「REAPEATBLE READ」コマンド操作 (9分43秒)
トランザクション分離レベルの「SERIALIZABLE」コマンド操作 (4分54秒)
MySQLの補足説明
『トランザクション処理』
データベースを利用するシステムにおいて、処理の一貫性を保証するために、関連する一連の処理全体を一個の処理単位として管理する仕組みのこと。
処理の途中でエラーが発生した場合、関連したデータ同士が矛盾を起こすため、適切にエラー処理を行う保証が必要となります。
『ダーティリード』とは
「Dirty read」(未コミット読み取り)の英語表記で、同時に実行されている他のトランザクションが書き込んでコミットしていないデータ変更を読み取る現象。
『ノンリピータブルリード』とは
「Non-Repeatable read」(反復不可能読み取り)の英語表記で、他のトランザクションの更新前とコミット後のデータを読んでしまうことにより、一度読み込んだデータを再読み込みすると結果が異なる現象。
『ファントムリード』とは
「Phantom read」(幻影読み取り)の英語表記で、別のトランザクションでデータの挿入、削除を行うとき、同じ検索条件で読んでいるのに、あったはずの行が消えたり、なかった行が現れたりする一貫性がなくなる現象。
『ACID』とは
「Atomicity」(これ以上分解してはならないという意味の原子性/不可分性)、「Consistency」(一貫性)、「Isolation」(独立性)、「Durability」(永続性)の4つの性質を表す頭文字を合成したもので、トランザクション処理の信頼性を保証するために求められる性質であるとする考え方で1970年代後半にジム・グレイが定義したものです。
『MVCC』とは
「MultiVersion Concurrency Control」の略で、トランザクションの書き込み処理中に他ユーザによる読み取りアクセスがあった場合、書き込みの直前の状態(スナップショット)を処理結果として返す処理。
書き込み中も読み取りができ、読み取り中でも書き込みができるトランザクション分離レベルのRead Committed (確定した最新データを常に読み取る) の処理。
MySQLリファレンス
参考資料の表示
推奨参考図書
「MySQL徹底入門 第3版 ~5.5新機能対応~」(翔泳社)