Carpe Diem

  Top > スポンサー広告> MySQL > トランザクションの動作を確認してみる  

スポンサーサイト

-- - --/-- [--] - --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

トランザクションの動作を確認してみる

2014 - 08/15 [Fri] - 10:23

よくACID特性って聞くけど、Iの独立性ってどうなってるんだろうと思っての動作確認です。

◆事前準備
データベースとテーブルを作っておきます。


mysql> create database transaction_test;
mysql> use transaction_test;

mysql> create table user(
-> id int(10) unsigned not null,
-> money int(10) unsigned not null,
-> PRIMARY KEY(id));

データも入れておきましょう。


mysql> insert into user (id, money) values(1, 1000);
mysql> insert into user (id, money) values(2, 2000);
mysql> insert into user (id, money) values(3, 3000);

こんな状態です。

mysql> select * from user;
+----+-------+
| id | money |
+----+-------+
| 1 | 1000 |
| 2 | 2000 |
| 3 | 3000 |
+----+-------+
3 rows in set (0.00 sec)



◆やること
やることは複数のトランザクションで同じレコードを変更することです。
①開始(A)
②開始(B)
③id: 1を変更(A)
④id: 1を変更(B)
⑤終了(A)
⑥終了(B)

気になるのは③、④の時にどうなるか、ですね。では実験してみましょう。


◆実験
①開始(A)

-- ターミナルA
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


②開始(B)
別のトランザクションにするために別ターミナルで実行します。

-- ターミナルB
mysql> use transaction_test;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)


③変更(A)

-- ターミナルA
mysql> update user set money=500 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0


④変更(B)

-- ターミナルB
mysql> update user set money=0 where id=1;

するとここで固まります。トランザクションAの方で編集しているので、このレコードにロックがかかっているということですね。

⑤終了(A)

-- ターミナルA
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

このコミットと同時にレコードのロックが外れますので、先ほどのターミナルBを確認してみると

mysql> update user set money=0 where id=1;
Query OK, 1 row affected (4.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

ロックのため4秒という長い時間の処理でしたが、ちゃんと変更されるようになりましたね。
ちなみにずっと放置するとタイムアウトで強制的に処理がキャンセルされます。

⑥終了(B)
この段階でターミナルAで値を確認すると、

-- ターミナルA
mysql> select * from user;
+----+-------+
| id | money |
+----+-------+
| 1 | 500 |
| 2 | 2000 |
| 3 | 3000 |
+----+-------+
3 rows in set (0.00 sec)

まだトランザクションが完了していないのでBの変更は反映されてないです。
ではターミナルBでもコミットします。

-- ターミナルB
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

もう一度ターミナルAを確認してみます。

-- ターミナルA
mysql> select * from user;
+----+-------+
| id | money |
+----+-------+
| 1 | 0 |
| 2 | 2000 |
| 3 | 3000 |
+----+-------+
3 rows in set (0.00 sec)

値が反映されるようになりました。
この行ロックのおかげで、他のトランザクションの処理による矛盾が生じなくなるのですね。

コメントの投稿





管理者にだけ表示を許可する

 | ホーム | 

プロフィール

Cicatrice

Author:Cicatrice
備忘録

検索フォーム

カテゴリ

最新記事

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。