ひがやすを技術ブログ

電通国際情報サービスのプログラマ

キャッシュとアスペクト

キャッシュは難しいテーマだと思います。
ばら色に見えて実は有効に機能していない分野だと
思うからです。
どこでキャッシュされるのかという点で考えてみます。


業務ロジックのうち、データアクセスに絡まない部分を
Logic(サービス)層と呼ぶことにすると、Logic層で
キャッシュが有効なのは、結果を導き出すために必要な
データが不変で、処理そのものには時間がかかる場合でしょう。
普段そのような状況にあまり出会わないような気がしますが、
であったとしても、アスペクトで処理せずLogic層に直接処理を
記述した方が良いと思います。
アスペクトは、複数のクラスにまたがる共通的な処理を
おこなう場合に有効に機能しますが、Logic層でのキャッシュは
Logic層固有のものだと思うためです。


次はデータにアクセスするDao(永続化)層のキャッシュですが、
トランザクション中のみ有効なキャッシュ
(ショートキャッシュと呼ぶことにします)と
トランザクションを超えて複数の画面間で共有されるような
キャッシュ(ロングキャッシュと呼ぶことにします)
に分けて考えてみます。


ショートキャッシュはリスクの少ないキャッシュです。
トランザクション中なので、他のトランザクション
同じデータに更新が入る場合も、RDBMSなどのリソース層の人が
うまく制御してくれます。
しかし実際は、トランザクション中に同じデータにDaoを使って
アクセスすることはあまりないでしょう。
EntityにアスペクトとしてDaoが埋め込まれるケースは後述します。


ロングキャッシュはリスクの多いキャッシュです。
複数のトランザクションで更新されたデータの同期を
取る必要があります。
また、クラスタリングされている環境では、複数の
サーバ間でもデータの同期を取らなければなりません。
外部からキャッシュとは無関係にデータを更新されることが
あってもいけません。
このようにロングキャッシュはいろいろ難しいことが多く、
まだこなれたものになっていません。
成熟しているRDBMSのキャッシュに任すのが無難で現実的でしょう。


最後は、データそのものであるEntity層でのキャッシュです。
Entityが他のEntityと関連がある場合に、getterメソッドで
キャッシュをおこないます。
POJO(特定のAPIに依存していない普通のJavaのオブジェクト)を
使う場合、getterメソッドにアスペクトを使ってDaoを埋め込む
ことになるでしょう。
ショートキャッシュなら有効だと思います。


文体ですが、シュール&ブラックだと
女の子受けが悪い
こういちさんにいわれた気がするので(ちょっと違ったかも)
かなりやさしいモード、いわゆるKモードに変えてみました。