ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

CakePHPのトランザクションを試してみる

スポンサードリンク

http://www.flickr.com/photos/23401669@N00/5118876374
photo by Son of Groucho



こんな記事を見た。


嵐のコンサートがあるとダブルブッキングしてしまうホテル予約システムを作ってみた | 徳丸浩の日記



((((;゚Д゚))))ガクガクブルブル


CakePHPは大丈夫なの?


試してみる。(macです)



siegeのインストール

$ brew install siege


# テスト
# 10ユーザーが10のリクエストした結果
$ siege -c 10 -r 10 -b http://www.google.com > /dev/null

done.

Transactions:		         200 hits
Availability:		      100.00 %
Elapsed time:		        6.58 secs
Data transferred:	        1.69 MB
Response time:		        0.28 secs
Transaction rate:	       30.40 trans/sec
Throughput:		        0.26 MB/sec
Concurrency:		        8.65
Successful transactions:         200
Failed transactions:	           0
Longest transaction:	        1.32
Shortest transaction:	        0.13


JMeterより便利やで・・・・!(°ω° !

テーブルとコードの準備


テーブルは記事のまま。コードはCakePHPに合わせて書き足しました。


時間あればgithubにあげておきます。

試してみる。

検証コマンド

$ siege -b -i -c 200 -r 100  --file=url.txt --log=urls.log

1回目


およ? 特に問題はなかった。トランザクション処理されているのかな?

mysql> select * from rooms_available;

                                                                                                          • +
id date room_type available reserved
                                                                                                          • +
1 2015-09-18 1 0 230
2 2015-09-19 1 0 230
3 2015-09-20 1 0 230
4 2015-09-21 1 0 230
5 2015-09-22 1 0 230
6 2015-09-23 1 0 230
                                                                                                          • +

謎が生まれる

  • あれ? MyISAMトランザクション処理は扱えないのでは?
  • ログみたら凄い量のエラーが発生。あれ?データは軽いはずだけど?なんでこのエラーが?

SQLSTATE[HY000] [2006] MySQL server has gone away

2回目


コマンド実行時で大量のエラーが(°ω°

[error] descriptor table full sock.c:119: Too many open files


多分だけど、ulimitだと思う。確認してみる。

$ ulimit -n
256


少なっ!!!! まじかよ。


値を大きくする。(OSの再起動が必要です)

$ sudo vim /etc/launchctl.conf

#####
limit maxfiles 65536 65536
#####

3回目


うーむ。やはり起きない。

mysql> select * from rooms_available;

                                                                                                          • +
id date room_type available reserved
                                                                                                          • +
1 2015-09-18 1 0 230
2 2015-09-19 1 0 230
3 2015-09-20 1 0 230
4 2015-09-21 1 0 230
5 2015-09-22 1 0 230
6 2015-09-23 1 0 230
                                                                                                          • +

6 rows in set (0.00 sec)

検証者のスクリプトで試してみる


test.phpってファイル名で保存しています。

検証コマンド

$ siege -b -i -c 200 -r 100  --file=url_test.txt --log=urls_test.log

1回目


起きた!!!!!キタ━(゚∀゚)━!

mysql> select * from rooms_available;

                                                                                                          • +
id date room_type available reserved
                                                                                                          • +
1 2015-09-18 1 0 316
2 2015-09-19 1 0 342
3 2015-09-20 1 0 313
4 2015-09-21 1 0 326
5 2015-09-22 1 0 298
6 2015-09-23 1 0 335
                                                                                                          • +

6 rows in set (0.00 sec)


何故CakePHPでは発生しないのかね(´・ω・`)???

考察


色々考える。

単純に処理が遅いならavailableを減らす


alvailableの値を30ぐらいにしてみます。

mysql> select * from rooms_available;

                                                                                                          • +
id date room_type available reserved
                                                                                                          • +
1 2015-09-18 1 0 30
2 2015-09-19 1 0 30
3 2015-09-20 1 0 30
4 2015-09-21 1 0 30
5 2015-09-22 1 0 30
6 2015-09-23 1 0 30
                                                                                                          • +

6 rows in set (0.00 sec)


ダメでした\(^o^)/

CakePHPトランザクション処理がある?


調べてもそんな記述はありませーん。


あるんだけど、プログラム書かないとトランザクションしないよって記述が多い。


また、デフォでは2.6.0から有効になるらしい。今回は2.5.8 /(^o^)\


ソースも読んでみたけど、atomicという値がないとダメみたい。そもそもsave()は、トランザクションの処理がなかった。

<?php
	$transactionBegun = false;
	if ($options['atomic']) {
		$db = $this->getDataSource();
		$transactionBegun = $db->begin();
	}

まとめ


うーむ。よくわかりません。なんでだろうか。