読者です 読者をやめる 読者になる 読者になる

ありんこオフィスに行ってみた

雑記

シェアオフィス、コアワーキングスペースのありんこオフィスに先日行ってみました。

シェアオフィス【東京・渋谷】ありんこオフィス

 

土曜日のお昼すぎでしたが、賑わっていてほぼ満席でした。

 

良い所

  • ドロップインで一日ずっといても¥1000で利用できる
  • フリードリンクがそこそこ豊富
  • 食べ物持ち込みOK

微妙だったところ

  • 椅子と机が長時間作業するにはちょっとつらい→一部良い椅子があったので運がよければ大丈夫

 

Gitのお便利設定

git

Gitを使い始めたらやっておきたい便利な設定いろいろ : アシアルブログ

 bashのプロンプトにブランチ名を表示する際、上記エントリの情報だと古くてエラーになる。

-bash: __git_ps1: command not found

bash_completionで「-bash: __git_ps1: command not found」となった時の対処法 - くりにっき

こっちも参考にしつつ

git/contrib/completion/git-prompt.sh at master · git/git · GitHub も入れればOK

 

nokogiriとMechanizeでスクレイピングその1

Ruby

趣味の関係でmixiをたまに使うのですが、(毎日見てないので)特定のコミュの書き込みがあったらメール飛んでくるようにしたいなと思いチャレンジ。

 

とりあえずログインして中の情報をなんとなくとってくるとこまで。

 

文字コードをちゃんと設定してないせいか、\nがたくさん出てる。

 

参考

スクレイピングのためのNokogiri利用メモ - それはそれ。これはこれ。

RubyのMechanizeを解説 for 1.0.0 - きたももんががきたん。

RubyのNokogiriでギコギコスクレイピングだ | メモ帳代わりのブログ

Macでの開発環境構築

参考にしたリンク集

 

Macbook Pro Retinaを買ってからやったことまとめ - kidomahの日記

Mac OS X Lion で Ruby on Rails の開発環境を1から構築 - Qiita [キータ]

Ruby - Mountain Lion環境への「rbenv」のインストール手順 + 設定方法 - Qiita [キータ]

Homebrew で Apache, PHP, MySQL, Composer をインストールして Yii Framework を動かすところまで - Qiita [キータ]

 

 技術関係はここじゃなくてQitaでいい気がしてきた。

エンジニアの給料

雑記

エンジニアに最も高給を支払っている企業は意外にも・・・? | THE NEW CLASSIC

うーん、高いですね。

どの企業も世界的企業なので、単純に日本の企業と比較はできないかもしれませんが、やっぱりすごく高いと感じちゃいますね。

 

日本の企業で高そうなイメージだとDeNAGreeでしょうか。

 

DeNA、GREE、サイバーエージェントの平均年収を比較してみた | CyberTimes [シバタイムス]

 

なぜ日本のエンジニアは地位が低いのか?その傾向と対策 - paiza開発日誌

仕事の報酬は仕事

雑記

こんな記事がTLに流れてきました。

スタバはなぜ値下げやテレビCMをしない?高いブランド力構築の戦略を元CEOに聞く
http://zasshi.news.yahoo.co.jp/article?a=20131012-00010000-bjournal-bus_all&1381526511


この記事の中で気になったのが、「仕事の報酬は仕事」という言葉。
調べてみたら、昔からある言葉みたいですね。(誰が最初か、というのはよくわかりませんでしたが)


良い言葉だとは思いますが、一歩間違うと社畜一直線にもなってしまうので、使い方には注意が必要だなーと感じました。

http://www.gexeed.co.jp/column/cl018.html
http://bizmakoto.jp/makoto/articles/1106/08/news012.html
http://www.esofken.com/rensai/1011.html

仕事の報酬でより良い仕事を得て、その循環の先に何があるのか。
だから、給料は大事じゃない(低くても良い)って論調になると、違うんじゃないかな、と思います。どっちが大事って事ではなく、どっちも大事。


私は仕事が好きですが、仕事以外にも好きな事がいっぱいあるので、それを実現するためにはお金と時間が必要です。


結局、多くの人にとって人生の大部分を占める仕事において、何を求めるか、という哲学的な話になってくるのでしょうか。。。

InnoDBとREPEATABLE READとSELECT FOR UPDATEと楽観ロックその2

MuSQL

前回の話に排他(行ロック)を絡めてみる。


Versionカラムを使った楽観ロックをしてみます。

■ストーリー
1.セッション1 トランザクション開始
2.セッション2 トランザクション開始
3.セッション1 行情報取得→versionカラムを使って楽観ロックをした更新→commit or rollback
4.セッション2 行情報取得→versionカラムを使って楽観ロックをした更新→commit or rollback

楽観ロックなので、1行も更新できなかった場合はrollbackする想定です。

長いので1,2は省略しちゃいます。

READ COMMITTED

セッション1

mysql> select * from Version;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


通ってしまいます。

REPEATABLE READ

セッション1

mysql> select * from Version;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

mysql> select * from Version;
+----+---------------------+---------+
| id | text                | version |
+----+---------------------+---------+
|  1 | updatedFromSession1 |       2 |
+----+---------------------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


こちらも通ってしまいます。


ここでストーリーを少し変えて、

■ストーリー
1.セッション1 トランザクション開始、tempテーブルselect
2.セッション2 トランザクション開始、tempテーブルselect
3.セッション1 行情報取得→versionカラムを使って楽観ロックをした更新→commit or rollback
4.セッション2 行情報取得→versionカラムを使って楽観ロックをした更新→commit or rollback

tempテーブルのselectを入れただけです。(for updateは無し)


READ COMMITTED

セッション1

mysql> select * from Version;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.01 sec)

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

mysql> select * from Version;
+----+---------------------+---------+
| id | text                | version |
+----+---------------------+---------+
|  1 | updatedFromSession1 |       2 |
+----+---------------------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

変更前と同じ。


REPEATABLE READ

セッション1

mysql> select * from Version;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

mysql> select * from Version;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)


なんと結果が変わります。
REPEATABLE READの場合、最初のselectのタイミングで取得するデータのスナップショットが決まるらしいです。
http://dev.mysql.com/doc/refman/5.1/ja/innodb-consistent-read.html

今回だと、2でtempをselectした時点でセッション2中でselectの結果として返ってくる値が全テーブルで確定するようです。

というわけで、1,2の処理にinsertやらが入っていても、REPEATABLE READなら排他がばっちり決まります。



またストーリーを少し変えてみます。

■ストーリー
1.セッション1 トランザクション開始、tempテーブルselect
2.セッション2 トランザクション開始、tempテーブルselect
3.セッション1 行情報取得(for update)
4.セッション2 行情報取得(for update)※トランザクション1のコミット待ち
5.セッション1 versionカラムを使って楽観ロックをした更新→commit or rollback
6.セッション2 versionカラムを使って楽観ロックをした更新→commit or rollback


楽観ロックがかかってるのに、for updateで悲観ロックをかけたとします。
で、コミットのタイミングを変えました。


READ COMMITTED

セッション1

mysql> select * from Version where id = 1 for update;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

セッション2

mysql> select * from Version where id = 1 for update;

ロック開放待ち。

セッション1

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

+----+---------------------+---------+
| id | text                | version |
+----+---------------------+---------+
|  1 | updatedFromSession1 |       2 |
+----+---------------------+---------+
1 row in set (8.33 sec)

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


REPEATABLE READ

セッション1

mysql> select * from Version where id = 1 for update;
+----+------+---------+
| id | text | version |
+----+------+---------+
|  1 | init |       1 |
+----+------+---------+
1 row in set (0.00 sec)

セッション2

mysql> select * from Version where id = 1 for update;

ロック開放待ち。

セッション1

mysql> update Version set text = 'updatedFromSession1' , version = version + 1 where id = 1 and version = 1; 
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

セッション2

+----+---------------------+---------+
| id | text                | version |
+----+---------------------+---------+
|  1 | updatedFromSession1 |       2 |
+----+---------------------+---------+
1 row in set (7.38 sec)

mysql> update Version set text = 'updatedFromSession2' where id = 1 and version = 2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

なんと、通ってしまいました。
REPEATABLE READでトランザクション開始後に1度selectしていても、select for update をかけると他トランザクションの影響を受けてしまうようです。

まとめ

REPEATABLE READの場合、READ COMMITTEDに比べて楽観ロックがシビアに効くこと場合がある。
ただし、select for updateで悲観ロックするとREAD COMMITTEDの場合と同じになる。

既存処理で、楽観ロックだけどシビアに排他が効いてる処理を、
何気なく悲観ロック追加すると挙動が変わる場合があるので注意する。


InnoDBトランザクションは、ネクストキーロックとかもあって、
ハマるポイントが多いですね。。