2015年7月21日火曜日

【Azure】体験版起動

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はMicrosoft Azureについて連載中です。
事前調査は前回までで切り上げて、そろそろアプリの作成に入っていきましょう。

無料版を探せ

まずはAzureがどんなものか、無料範囲で検証していきたいと思います。
しかし、さっそく行き詰まる所が……。
無料バージョンが複数見つかるんですよね。



それぞれ、


  • ①体験版
  • ②一ヶ月無料版
  • ③一ヶ月無料版(別リンク)


紛らわしいわ!!

何が違うかと言いますと、
①はWebAppを本当にチョチョイとお手軽に初めて見るインスタント体験版、
②③はフルパックを1ヶ月間だけ無料で出来るコースのようです。

何でこんな構成になっているのか経緯は調べようもありませんが、恐らくは過去にそれぞれ別サービスだった頃の名残だと思われます。

今でこそAzureは「App Service」という一つのサービスに統合されていますが、昔は「Web Apps」「Virtual Machine」など機能に応じて別々に展開していました。
別々だった頃にそれぞれ別々に無料プランがあった。
その名残で、①と②のように違う無料プラン、②と③のように同じものでもリンクが違う、といった状況になっているのだと私は考えています。

やっぱりAzureと言うかクラウド業界はまだまだ発展段階なのですね。

完成された技術領域でやっていると無いことも、こういう発展途上領域だと「あれっ?」っていうことが結構出てきます。
そういうのも含めて気ままにやっていきましょう。

体験版を選択

では、上記の中から、今回は体験版を選びたいと思います。

  • http://azure.microsoft.com/ja-jp/services/app-service/web/


数秒で開始できます。とのこと。実に早いですね。
Webサイトを始めるのに必要な設定が最初から揃っている所からスタート出来るのがAzureの魅力の一つです。

次に、言語を選択します。
プランは以下。

  • C#
  • 空のサイト
  • HTML5
  • Java
  • NodeJs
  • PHP
  • Python

選択した言語のランタイムが適用された状態からスタート出来るものと思われます。

しかし「HTML5」って要は単なるhtmlだろと突っ込みたくなりましたが、これはつまり、普通のホームページもAzureに引っ越ししろというアピールなのでしょう。

「単なる普通のホームページなんて、普通のレンタルサーバにFTPでファイルを置けば十分」みたいに思っている人は多いでしょうけれども、
言語を実行しない単純なホームページでも、クラウド化する価値は十分にある!!

急にアクセスが増えても落ちませんし、バージョン管理も体系化出来ますし、高度なアクセス解析機能が使用出来るようになったり。値段も安くなるんじゃないかな?
単にHTMLファイルを一個置くだけでも技術革新はあるのです。

それはさておき、今回は言語はPHPを選択したいと思います。


作成画面

PHPを選んで、Webアプリの作成を実行します。
すると、以下のように英語版の画面に飛ばされてしまいました。


クラウド界ってこのパターンが非常に多いのですが、日本語化が中途半端なのですよ。
細部に渡って細かく日本語を整備するのが面倒だから以外に理由など考えられませんが、
むしろ「プロのSEなら面倒がらずに英語くらい読めよ」の方が正論でしょう。

下の方に進むと以下の項目があります。


前の画面で選択したPHPがデフォルトでセットされています。

ここから選択肢は2つ。

  • PHP Empty Site
  • PHP Starter Site

EmptyはHello World状態、Starterはそこそこ色々取りそろえ状態からスタートです。
今回はStarterを選択します。

Create

PHP Starter Siteを選択して、Create実行!!

この直後にサインインが求められますが、サインインしてから数秒後、サイト完成ッ!! 速いッ!!


ランダム文字列みたいなURLが出ていますので開いてみますと、以下のようなサイトが出来上がっていました。
これがスターター画面なのですね。


本当に数秒でスタート出来てしまいました。

しかし、開発者の観点からですと、「これってどうやって動いているんだろう?」まで調べておかないと意味無いです。
親切なことに、このスターターサイトはGit連動しているようなので、Gitでソースを取得してみましょう。

その結果がこちら。


なるほど。
普通にPHPですね。
既にDBにも接続されており、正にスタート状態です。

ここから先は普通にソースをプッシュしていけばサイトを作っていけるというわけです。
いやぁ、便利なものですね。

終わりに

と言うわけで、難なくサイト構築まで辿り着くことが出来ました。
ちなみに上記は体験版につき、1時間しかサイトが残留しません。

本格的には一ヶ月無料版を選ぶ必要があるので、また次回からやり直しです。

しかし、体験版により開発風景の感触を掴むことは出来ましたね。
よく出来ていると思います。

スムーズにキックオフ出来たことですし、今後も頑張って行きたいです。

2015年7月8日水曜日

【Azure】ソリューションチェック2

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はMicrosoft Azureについて連載中です。
始めたばかりですので、今は導入部分を調査中です。

Web Appsを選択


Microsoft Azureは非常に高機能なサービスですが、前回の記事にて、一際Azureが推している六大機能についてザッと概要をさらってみました。

次はその中の機能を掘り下げていきたいと思います。

私が狙いを定めているのは「Web Apps」でして、Azureの中でも一番の代表機能。
SaaSを提供してくれるサービスです。

これについて調査をしていきます。


Web Appsの中身

では、下記URLに進んで、Web Appsの概要をチェックしてみましょう。


言語

Web Appで使用出来る言語は、今のところは以下の模様。

  • .NET
  • Java
  • PHP
  • Node.js
  • Python
  • C#
  • Ruby

ふむ。Javaエンジニアたる私としてはJavaがあれば事足りますが、それ以外にも色々あるようですね。
「Microsoftなんだから.NETなんじゃないの?」というイメージを持っておられる方もいるようですが、別にそんなことはありません。

ここで一つ困ってしまうのは、上記のページにはRubyについて全く何も載っていないのですけど、実際にはあるんです。



公式の説明サイトの更新が遅れている?
もしくは手抜き?

困りますねぇ。

まあ、GAEの調査をしている時もそんな感じでしたが。

クラウド関連って、公式にドキュメントが揃っていることを期待してしまいガチですけど、実際はそうじゃない方が主流な気がします。
自分で情報を追えない人は置いてきぼりにされるシビアな世界なのかもしれません。

DB

選択可能なDBは以下2つ。

  • SQL Database
  • My SQL

基本的にはMicrosoftの誇るデータベース「SQL Server」のクラウド版「SQL Dasabase」を選択するのが良さそうな感じですね。
せっかくのクラウドなんですから、クラウドを生かしていきましょう。

元々がLAMPP構成なアプリを移植したいなど、どうしてもという都合がある場合は「My SQL」という選択肢もあるようです。

私はDatabaseの中ではPostgresが好きなのですが、Postgresは使えません。残念です。

スケールアウト

クラウドの目玉は、負荷が高まった時にスケールアウトして処理性能を向上させることが出来る点でしょう。

しかし、そのスケールアウトには二つのやり方があります。「手動」と「自動」です。

手動というのは、その名の通り「このサイトはインスタンスを2コ立ち上げておく」「サイトの人気が出たから3コに増やす」と、管理者が任意で規模を指定するやり方です。
管理者が油断している隙にアクセスが急増するとサイトがダウンするのが欠点です。

対して自動というのは、アクセスが増えると勝手にインスタンス数も追加されるというやり方です。
管理者が何もしなくても自動で増減してくれるので落ちる心配はありませんが、急にアクセスが増えて高額使用料を請求される恐れがあるのが欠点でしょうか。

さて、Azureはと言いますと、どうやら今は両方提供してくれているようです。(昔は手動だけだった模様)

やっぱりクラウド基盤は落ちないのが売り物ですから、私は自動機能を使わせて頂きたいですね。

Gitコミット

最近はこのやり方が増えていますね。

モジュールをリリースする場合、従来のやり方だとモジュールを手動でサーバ上において、更にAPPサーバを再起動するなどの作業が必要です。
その際にオペレーションミスがあってサイトがダウンしてしまうとか、バグがあって急遽切り戻さなきゃいけないとか、そういうブルーな事態は結構あるものです。

しかし、AzureはGitに対応しています。
GitでPushしてあげれば、その瞬間にリリース完了。
逆に切り戻したい場合は履歴を戻って選択すればOK。

非常に合理的な管理が出来るわけです。

オマケ:WordPressパック

さて、私はこれから自分でサンプルアプリを作るつもりですが、上記の情報で一先ず開発に着手出来そうです。

なので私は使用しませんが、オマケで次の話も記述したいと思います。

Azureは「WordPress」に対応しています。
最初からオススメ標準セットという形で、WordPressやその他いくつかのパッケージが入った状態で準備されておりまして、クリック一発でそれらがセットアップされた状態から開発に着手出来るわけです。




このように、「自分で一から作っていく」のではなく「可能な限りAzureが用意してくれている機能を活用する形で開発する」という発想を持つことが、Azureを有効活用するポイントと言えるでしょう。

終わりに


以上で事前調査は終了としまして、次からは実際にWebアプリの起動に入っていきたいと思います。

2015年6月30日火曜日

【Azure】ソリューションチェック1

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はMicrosoft Azureについて連載中です。
初心者につき至らぬ部分も多いかと思いますが、最後までお付き合い下さい。

クラウドの個性とは?

さて、そもそもとしまして、クラウド基盤を使うことにどんな利点があるのか?
そう問われれば、まず出てくるのが以下の辺りでしょう。

  • 自前でサーバを持たなくて良い。
  • 保守が楽。
  • コスト効率が良い。
  • 大量アクセスにも対応可能。

まあそうなんですけどね。

しかし、世の中にはクラウド基盤は沢山あるのです。
そして大概のクラウド基盤は上記の要件を満たしています。
(満たしていないのにクラウドを騙る詐欺サービスもありますが、私はそれをクラウドとは認めません)

では、どんなクラウド基盤でも上記の要件を満たすわけだからクラウド基盤はどれを使ってもみんな同じか?
違います。
クラウド基盤には個性が存在します。

「あっちのクラウド基盤には出来ないけど、私の所の基盤なら出来るよ!!」

という要素が存在するのです。
なので、クラウドの個性を意識せずに『クラウド』と言ってしまうのは、言わば以下のような感じ。

  • DBはみんな同じじゃないの?⇒いや、SQLが使えるのは同じだけど、OracleにはあるけどMySqlには無い機能もあるよ。
  • パソコンはみんな同じじゃ無いの?⇒いや、MACとWindowsで全然違うよ。
  • 温泉ってどこも同じじゃ無いの?⇒いや、あっちは風呂入って寝るだけ。こっちはマッサージも用意してある。
  • 洗剤ってみんな同じじゃないの?⇒使ってみれば直ぐ分かるけど結構違うよ。

クラウドの個性を知らずにクラウドを始めるのは、
こいくち醤油とうすくち醤油の違いを知らずに料亭を始めるようなもの。

こんなノリじゃマトモなサービスは提供出来ないですよね?
なので、クラウドを始めるときは、まずそのクラウドの個性を知るところから始めなければなりません。

ソリューションチェック

では、Microsoft Azureにはどんな個性があるか?
そこを調査していきたいと思います。

クラウドの個性と言っても、正直な話、機能や値段、拡張性、開発効率などなど色々あり過ぎて全部は追いきれません。
このため、今回は余り深掘りはせずに、ショートスタート。
とりあえず始めるにあたっての初歩的な所から調査していきたいと思います。


まず、Azureのトップページに載っているのがこちらです。


6種類のソリューションが載っていますね。
これがAzureのイチオシする6大機能と言って差し支えないでしょう。

それぞれ解説を以下に記載します

Web Apps

Azureの代表的サービス。SaaSと呼ばれるクラウドの中でも代表的な形態の一つ。
Webアプリケーションの展開に最適なパッケージです。

「Windows Server」と「SQL Server」が最初から用意されており、開発者は自前のアプリを載せる所からスタート出来ます。
楽チンですね。

しかし、逆に言えば「Windows ServerじゃなくてLinuxがいいんだけど」「SQL ServerじゃなくてOracle使いたい」みたいな要望には対応出来ません。
最初から決まった構成で構築済みのサーバにみんなで便乗するのがSaaSですから。
制約がある反面、安く使わせて貰えるのがメリットです。

Visual Machine

Azure第二の弾丸。IaaSと呼ばれるクラウドの中でも代表的な形態の一つ。
早い話が、仮想マシンを丸ごと1コ借りるイメージでしょうか。

Linux、Oracleなど大概の要件には対応出来ますが、自分で一から構築しなければなりませんし、そこそこ値段もするのがデメリット。

それなら自分でサーバを持つのと何が違うかって?

これは仮想マシンを借りるだけですので、物理的にサーバを買う必要が無く、それだけ初期費用が安いですよね?
また、サーバが物理的に故障することもありません。
地震でデータセンターが海の底に沈んでデータが消し飛ぶ心配もしなくて良いです。
物理的制約から解放されるだけでも価値があるのです。

地震が心配なら日本のデータセンターを使うな、という一つの結論がここにあります。

(まあ、Microsoftの運営する複数のデータセンターが同時に核ミサイルの攻撃を受けたら流石に終わりでしょうが、それを言っちゃあ何も出来ません)

なお、クラウド界の王者であるAmazonAWSも似たようなサービスを提供しています。

SQL Database

Microsoftの誇るデータベース「SQL Server」とは別の話なので注意!!
「SQL Database」という、大量処理に特化したデータベースを提供して頂けるようです。

「大量負荷に対応する為には、普通のDBではなく大量処理対応型DBが必要」

この要件に対応するためのものですね。

Mache Lerning

クラウド分析の予測サービスと言う触れ込みです。

「自分のサイトにログインしているこの人は、他にどんな商品に興味があるのかな?」とか、「最近の世の中の流行キーワードは?」とか、そういうことを分析出来る機能を提供している模様です。

私はこの手のマーケティング手法は未経験者ですので敷居が高いですが、連載を続けるにつれて、これらの機能についても検証していきたいと思います。

モバイルバックエンド

スマホアプリの拠点として稼働する各種機能を備えたソリューションです。

普通のWebサイトと、スマホ向けサイトって何が違うのかって?

例えば、スマホでSNSとかを使っていると、「○○さんが投稿しました」みたいな通知が来ますよね?
あれは「プッシュ通知」と言いまして、拠点となるサーバ側から情報を送り込んでいるのですよ。

そういうスマホ特化機能が目白押しのソリューションです。

RemoteApp

Windowsを展開するMicrosoftならではの必殺技。
シンクライアントでWindowsOSを使用出来ます。

今現在、私達は自分のPCにOSを入れていますが、近い将来は一般ユーザに至るまで全部シンクラ化する可能性も十分にありますね。

終わりに

上記はAzureのトップページに載っている情報をサラッと眼を通しただけですが、それでもこれだけ豊富な機能があることに驚きです。
逆に言うと、勉強するべき要素が多いということでしょう。

これから頑張って調査を進めていきます。

最初は一番の代表サービス「Web Apps」で何かサンプルアプリを作ってみたいと思います。

2015年6月16日火曜日

【Azure】Microsoft Azure チャレンジ編 初めに

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

ここ最近はクラウド基盤「Google App Engine(以下、GAE)」について連載を継続してきましたが、世の中には他にもクラウド基盤は沢山あります。
他のクラウド基盤も調査して行かなければ……。

と言うわけで、この辺りで別のクラウド環境「Microsoft Azure」にチャレンジしていきたいと思います。

クラウドのシェア調査

まずは以下の図をご確認下さい。
アメリカの調査会社「Synergy Research Group」がリサーチした、クラウド環境のシェア率です。

Synergy Research Groupによるクラウド環境シェア調査


  • 1位:Amazon:27%
  • 2位:Microsoft:10%
  • 3位:IBM:7%

そこから先はGoogleの5%、SalesForceの4%と続くようです。
やっぱりAmazonが最強ですね。

上記のリサーチだとAmazonのシェアは27%ですが、私としてはちょっと意外です。
ネット上のニュースを見ていますと、「クラウド=Amazon」くらいの勢いで情報が氾濫しているような……。
私の中のイメージだとAmazonのシェアは75%くらいだと思っていました。

私が頑張ったGoogleは4位の5%です……。
まあ、面白いものだと思いますが、業務用としては如何なものかという面は確かにありますからね……。

ちょっとした便利アプリを作ってリリースするとか、WebAPIの拠点に特化するとか、限定されたシチュエーションであればGAEは最強だと思っています。
しかしながら、その条件に合致する案件が見当たりません。
ビジネスの路線として掲げるには些か厳しいところがあります。
チャンスがあれば案件で採用したいところですが、しばらくは様子見です。(残念)

5位はSalesForceです。
私はSalesForceについてもチラッと触ったことがあるのですが、あれはSalesForceに対する専門知識が要求されますね。
非常に難しいです。
また、SalesForceは特に営業支援ツールとしては非常に無敵のパワーを発揮するものですが、一方でその機能が使えるからこそ意味があるもので、
それ以外の関係無い案件には大して利点もありません。

私が思うに、GAEもSalesForceも、クラウド環境としての圧倒的高性能を有しながら、案件として採用出来るパターンの狭さ故に遅れを取っているイメージがあります。
適した案件を安定供給して貰えるなら大歓迎なのですが、それが無いビジネス環境ですと、活躍する機会に巡り会えません。

対してシェアNo.1を誇るAmazonはIaaSと言いまして、細かいことはさておき、仮想サーバを丸ごと一個借りるのに近いイメージ。
何でもありなのです。

対して、2位のMicrosoft AzureはPaaS形式と言いまして、簡単に言えば最初から用意されているWindowsServerにアプリだけ載せるようなイメージ。
Amazon程ではありませんが、自由も結構効きます。

3位のIBMは、ちょっと詳しくは存じませんが、IaaSとPaaSの両方をやっているようです。

これらから総合するに、私はクラウド市場をこのように考えています。

クラウド環境のシェア=汎用性である、と。

もちろん値段とか機能とかも重要ですよ?
でも、GAEやSalesForceみたいに機能・性能こそ最強でも個性が強過ぎるクラウド環境は案件が付いてこないのです。

「要件定義を完全にコントロール出来るならGAEという選択肢もあるが、実際にはそう都合良く行かない」

という現実が横たわっています。

クライアントから無茶な要求を言われても対応しなければいけない、という切実な事情を踏まえると、とりあえずAmazonみたいな汎用性の高いクラウド環境を選んでおくのが一番無難なんですね。

このシェア率はリスクマネージメントの結果が反映されているのだと、Tacyは考えています。

なぜAzureか?

以上により、クラウドを始めるならAmazonを選ぶのが一番無難でオススメです。

しかしですね、Amazonは仮想サーバを1コ借りるのに近いイメージの体制を取っているだけあって、設定作業という名のサーバ構築がそれなりに大変なのです。

自由度とのバーターなので仕方ありませんが、省ける作業は省きたいでしょう?

と言うわけで、自由度は1ランク下げても良いから、もう少しお手軽なクラウド環境を選ぶとなると……、それがAzureなんです。

例えば、DBはSQL Server限定とか、渋い制約を課せられてしまう部分も少なくないですが、一方で「それくらいの制約なら、こっち側で合わせてあげることができるかな?」と思えなくも無い。

自由度を取るか、保守性やコストパフォーマンスを取るか、絶妙なバランス感覚を要求される所ですが、Azure程度なら丁度良いんじゃないかと思うわけですよ。

そして、同じ事を考えている人も多いのか、Azureは成長度が違います。

AWSの成長度が2014年で51%なのに対し、Azureは96%!!

Azureの成長力はAWSの2倍!!

シェアならAmazonですが、成長力ならAzureが上なのです。
これはAzureの絶妙なバランス感覚を物語った数字な気がします。
まだしばらくAmazonの優位が続くと思いますが、いずれAzureが逆転するかもしれません。

総括しますと、

  • 完璧を期するならAmazon。
  • 最適を狙うならAzure。
  • 最強を目指すなら個別に吟味。

私はこのクラウド環境にこのようなイメージを持っています。
そして今回、私は後者についてチャレンジしてみようと思い立つに至りました。

終わりに

というわけで、来週からは新連載「Microsoft Azure」を初めていきたいと思います。

調査を完了してから執筆するのではなく、手探りで進めながらその風景を実況するという体裁で進行します。

長期連載になりますが、応援よろしくお願い致します。

2015年6月10日水曜日

【GAE】メール送信

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はクラウド基盤「Google App Engine(以下、GAE)」の連載中です。

今回のテーマはメール送信です。

実装


GAEのメール送信は簡単です。
まずはソースからどうぞ。

public void send() throws Exception {

        logger.fine("メール送信:開始");

        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("fromアドレス"));
        msg.addRecipient(
            Message.RecipientType.TO,
            new InternetAddress("toアドレス"));

        msg.setSubject("タイトル", Encode.ISO2022JP);
        msg.setText("本文");

        // 送信実行
        Transport.send(msg);

        logger.fine("メール送信:終了");

    }

特に特記事項はありませんね。
Java標準のメール送信ライブラリ「JavaMail」が使用出来ます。

サンプルはネット上に無数に転がっていますのでお好きなサイトを参考にして下さい。

特記事項:FROMアドレス

しかし、やっぱりGAEには特性があるんですね。
それは「FROMアドレス」の制限です。

メールというのは非常に脆弱性の多いツールでして、「スパム」というものがあります。日本語で訳せば迷惑メールです。
GoogleはGAEをスパムとして使われてしまうのを防ぐ為にスパム防止機能が入っています。それがFROMアドレス制限です。

以下の2種類のアドレスしかFROMに使用出来ません。

  • Google App Engine で Application の管理者として指定しているアドレス
  • 現在のログインユーザのアドレス

なので、「メール送信者は送信専用のダミーアドレスにしておきたい」とかは出来ないのです。
ちゃんと使用可能なアドレスをそのプロジェクトの『管理者』として登録する必要があります。ご注意を。

Gmai連動

しかし、不便なことばかりではありません。
GAEから送信したメールは、何とGmailと連動しているのです。

会社のアドレスなので画面キャプチャは載せられませんが、例えば上記の送信パターンの後者である「GAEアカウントでログインしているユーザのアドレス」で送信した場合、
Gmaiから「送信済みメール」を開きますと、GAE上で送信したメールの送信履歴が残っています。

なので、「メールの送信履歴を保存したい」という要望があった場合でも、自分で履歴管理機能を作り込まずとも、Gmailを見れば自動的に出来ているわけです。
これは凄い機能ですね。

業務用としては非常に信頼性を担保してくれるものだと思います。

費用

このようにキラリと光る便利なGAEメール送信機能ですが、大きな落とし穴も。
課金があるんですね。

ズバリ、
  • 最初の100通は無料。
  • 以後は、100通毎に0.01$
このような料金となっています。
メール如きで金を別枠にするなんて……、と思いますが、これもスパム対策なのかもしれませんね。

1通1円くらいの費用感覚ですので、何万通も無数にスパムを送ると赤字になるということにご注意下さい。

終わりに

以上です。

GAEからのメール送信は非常に簡単ではありますが、私としては「課金」がネックだと思います。

メールなんて前時代的なツールは使うな、というのが先進的なんじゃないでしょうか。

要件にも依りますが、どうしてもメールを大量送信しなければならないという都合がある場合、私だったらメール送信サーバだけは別に用意しますね。

メールの文面や宛先情報はGAE上に保存しておいて、メール送信サーバで常駐するメール送信バッチがGAEにアクセスする。
そしてデータだけ取得し、メール送信サーバにてメールを送信する。

こういう手順なら課金上限には悩まされずに済みますよね?

このように、場合によってはGAEの強い部分だけを活用し、弱い部分は潔く別に用意するという柔軟な戦術もGAEには必要なのです。

2015年5月28日木曜日

【GAE】初級実装編4 一意制約(更新パターン)

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はクラウド基盤「Google App Engine(以下、GAE)」の連載中です。

今回も前回に引き続き一意制約についてです。

やっぱりGAEに一意制約は無い


前回にもテーマにしましたが、GAEに一意制約はありません。
しかし主キー制約はあります。
よって、主キーのみのテーブルを作って主キー制約を実現するしか無いです。

まずは前回にも記載した新規登録の一意制約ソースを以下に張ります。

public Key insert(Shohin model) throws Exception {

  /*
   * トランザクション開始
   */
  Transaction tx = Datastore.beginTransaction();

  try {

   Key key = null;

   /*
    * 一意制約専用テーブルに登録する。
    */
   if (Datastore.putUniqueValue(Shohin.UNIQUE_SHOHIN_NAME, model.getShohinName())) {

    /*
     * 一意制約専用テーブルに登録が成功した場合
     */
    key = super.put(model);

   } else {

    /*
     * 一意制約エラー
     */
    throw new BusinessCheckException("対象の商品名は既に登録されています。");

   }

   /*
    * 正常な場合はコミットする。
    */
   tx.commit();

   return key;

  } catch (Exception e) {

   /*
    * エラーになったらロールバックする。
    */
   tx.rollback();
   throw e;

  }

 }


フローを手短に表現すれば以下になります。

①一意制約テーブルに新規登録する。
⇒失敗したら処理終了。
⇒成功したら次に進む。
②新規登録する。

でも、これって新規登録ですよね。

更新の時はどうやるの?というのが今回のテーマです。

ガチンコ勝負

実はこのブログは、執筆前にネットサーフィンしてネタをかき集めてきておりまして、
上記のソースも、実は本質的には他サイトのパクリのようなもの。(自分で書き直していますけどね)

上のソースの元となった、新規登録系のサンプルソースはネット上に沢山転がっていました。

しかし、どれだけ探しても「更新系」の話題がサッパリ見つからないのです。

恐らく、「更新系」については、特に便利な機能なんか存在しないのでしょう。
ガチンコでロジックを組み上げる以外に手は無いというのが私の結論です。

気合い入れて行きましょう。

ロジック


正確に言いますと、GAEにあるのは「put」と「delete」ですから、「新規登録/更新」などという区分けは技術的にはありません。
しかし人間の操作感では「新規登録/更新」では別物でしょう。
「put」を「新規登録/更新」で使い分けるには、以下ロジックが必要になります。


・対象データを検索する。
⇒データが存在していなければ新規登録。
⇒データが存在していれば更新。


一回find処理が必要になります。普通のSQLみたいにupdateは存在しません。

その上で、delete&insertで一意制約ロジックを実現することになります。

そのフローはこちら。

①一意制約対象のカラムが更新前と更新後で違うかどうかを判定する。
⇒同じである場合は普通にputして終わり。
⇒違う場合胃は次に進む。
②一意制約テーブルに更新後のカラムを新規登録する。
⇒失敗したら処理終了。
⇒成功したら次に進む。
③putする。
④一意制約テーブルに更新前のカラムを削除する。

一意制約カラム削除のメソッドは「Datastore.deleteUniqueValue」です。

これを使用したソースはこちら。

public Shohin update(Shohin updateModel) throws Exception {

   Transaction tx = Datastore.beginTransaction();

   try {

       /*
        * 既存を取得
        */
       Shohin model = super.get(updateModel.getKey());
       model.setEntityUpdate(updateModel);
       super.put(model);

       /*
        * 一意制約項目が既存と同じであれば、そのまま更新する。
        */
       if (StringUtils.equals(model.getShohinName(), updateModel.getShohinName())) {

           model.setEntityUpdate(updateModel);
           super.put(model);

       } else {

           /*
            * 一意制約項目と異なる場合は、更新を行ってから過去の一意制約照合用レコードを消す。
            */
           if (Datastore.putUniqueValue(Shohin.UNIQUE_SHOHIN_NAME, model.getShohinName())) {

               model.setEntityUpdate(updateModel);
               super.put(model);
               Datastore.deleteUniqueValue(Shohin.UNIQUE_SHOHIN_NAME, updateModel.getShohinName());

           }

       }

       tx.commit();

       return model;

   } catch (Exception e) {

       tx.rollback();
       throw e;

   }

}

普通のSQLであればUPDATE一発で済むのに、GAEではこんなにロジックを作らなければなりません。
超面倒ですね!!

GAEの特性を認識せよ


これにより、GAEには個性があるということがお分かり頂けたかと思います。
要点は二点です。

  • GAEで一意制約を実現するのは大変である。
  • GAEはputであって、insert/updateではない。新規登録と更新を分けるのは大変である。

要件定義する時に、エンジニアがこの辺りの事情に配慮して定義しなければいけないのです。

やっぱり、基本的にGAEの一意制約は、本当に本当に必要な場合以外は適応しないというのが大原則と考えて良さそうです。

終わりに

なかなかGAEの個性に悩まされた要件でした。

次はちょっと変わった実装、「メール送信」についてご紹介します。

2015年5月18日月曜日

【GAE】初級実装編3 一意制約(新規登録パターン)

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はクラウド基盤「Google App Engine(以下、GAE)」の連載中です。

今回は一意制約について検証してみます。

GAEに一意制約は無い


一意制約とは何か」は、割愛させて頂きます
(読者ならみんな知っているでしょう)

とにかく、結論から言わせて頂ければ、GAEに一意制約はありません。

GAEのBigTableは、要するにJavaの動きで言う所のMapだからなんでしょうね。

Mapは「key」を基準にvalueを登録しますよね?
だから「keyが重複しているか?」は主キー検索一発でチェック出来ますし、重複も物理的にありえません。

しかし、valueの重複が無いかはmap総当たりでチェックするしか無いのです。
GAEも同じような状況にあるのです。

BigTableで一意制約はありません。不可能です。

しかし、BigTableはデータベースですから、本当に厳密な一意性を確保しなければならないシチュエーションも存在します。

そこで活躍するのが、「一意制約専用テーブルを作って主キーを一意制約みたいに使う」というテクニックです。

GAEライブラリであるslim3にはこのテクニックを支援する機能があります。
今回はそれのご紹介です。


Datastore.putUniqueValue


この機能を実現してくれるメソッドは「Datastore.putUniqueValue」、これです。

まずはソースをご覧下さい。

public Key insert(Shohin model) throws Exception {

  /*
   * トランザクション開始
   */
  Transaction tx = Datastore.beginTransaction();

  try {

   Key key = null;

   /*
    * 一意制約専用テーブルに登録する。
    */
   if (Datastore.putUniqueValue(Shohin.UNIQUE_SHOHIN_NAME, model.getShohinName())) {

    /*
     * 一意制約専用テーブルに登録が成功した場合
     */
    key = super.put(model);

   } else {

    /*
     * 一意制約エラー
     */
    throw new BusinessCheckException("対象の商品名は既に登録されています。");

   }

   /*
    * 正常な場合はコミットする。
    */
   tx.commit();

   return key;

  } catch (Exception e) {

   /*
    * エラーになったらロールバックする。
    */
   tx.rollback();
   throw e;

  }

 }

これは「商品名の一意制約チェック」を想定したものです。

いくつかの新登場の情報が出てきていますね。

トランザクション


まず、GAEのトランザクションはコレです。
Transaction tx = Datastore.beginTransaction();

  • Transaction tx = Datastore.beginTransaction();
  • tx.commit();
  • tx.rollback();

読んで字のごとく。説明不要。

疑似一意制約


そして、今回の主題となるのはココです。

if (Datastore.putUniqueValue(Shohin.UNIQUE_SHOHIN_NAME, model.getShohinName())) {

「Datastore.putUniqueValue」

これで「そのキーだけが主キーのテーブル」が作成され、データが投入されます。
ちなみに、Shohin.UNIQUE_SHOHIN_NAMEは単なる固定値。制約のイメージとして一意に定義しています。

/** 商品名一意性約 */
 public static final String UNIQUE_SHOHIN_NAME = "UniqueShohin_ShohinName";


この状況で商品を登録すると、結果はこちら。



「UniqueShohin_ShohinName」というテーブルが作られて、その値は一意制約指定したキー1コだけですね?

こうすることで、主キー制約を一意制約として使い回すことが出来るわけです。


考察

以上のことから分かりますように、「一意制約一個作るのも面倒臭い!!」というのが結論です。
一意制約の数だけテーブル数も増えていってしまいますので、そう気軽に搭載するわけにはいきません。

よって、「何があっても厳密に一意を維持しなければならない!!」という場合を除いて、基本的に一意制約は付与しない方向が良いと思います。

例:メールアドレス

世の中には「メールアドレスをログインIDとして使う」というシステムがあります。
ログインIDが重複しては大変なので、メールアドレスの一意制約は必須。
こういう場合は手間を惜しまず一意制約を搭載しなければなりません。

例:商品名

一方で、この例で出した商品名はどうか?

「同じ商品のレコードが2つ以上あっては業務に混乱を来すから防ぎたい」

という需要があるとしましょう。
しかしですね、商品名なんて重複してたら更新すれば良いのですよ。

この一意制約チェックは「複数ユーザが同時に同じタイミングにレコードを登録した場合」に威力を発揮するもの。

「別々のユーザが同じタイミングで同じ商品名を入れるなんて、まず滅多に考えられない。商品登録前に普通にDB検索チェックするだけで99.999%は防げる。それでも重複した場合は手動修正して貰えばいいや」

という楽観的対処で十分です。

一意制約に厳密性を求めず、ロジックで制御した楽観的一意制約で済ませる。

手を抜ける所は手を抜くのも、GAE開発の一つです。

終わりに

今回は「新規登録」の一意制約をご紹介しました。
しかし、この一意制約はロジックで作り出している擬似的なものですので、「更新」の一意制約はまた違ったロジックを組まなければなりません。

次回は「更新一意制約」についてご紹介します。