ローカルキャッシュ

MyBatisで、同一トランザクション内で同じシーケンスから値を2回取得する
ようなコードを書くと、同じ値が返されてしまう。サンプルはこんな感じ。

<select id="nextId" resultType="Long">
    select nextval( #{name} ) as value
</select>
SqlSession session = ・・・;

SequenceValue sequenceValue = new SequenceValue();
sequenceValue.setName("seq_testid");
Long result1 = (Long) session.selectOne("Test1.nextId", sequenceValue);
System.out.println(result1);

// 以下があるとうまくいくけど、SpringとMyBatisを連携するので、
// sessionオブジェクトを直でさわりたくはない。
// session.clearCache();

Long result2 = (Long) session.selectOne("Test1.nextId", sequenceValue);
System.out.println(result2);


で、このresult1とresult2が同じになるという罠。
そもそも、ログを見ると2回目の取得処理でSQLが発行されていない。


調べていくと、どうやらこれのようで。
http://code.google.com/p/mybatis/issues/detail?id=126


以下のようにflushCache="true"を付けると、ローカルキャッシュがクリア
されるようで、2回目の取得処理でもSQLが実行され違う値が取得できる。

<select id="nextId" resultType="Long" flushCache="true">
    select nextval( #{name} ) as value
</select>


別にシーケンスに限ったことではなく、通常のSELECTのSQLでも
同じ動作になるみたい。
そもそも、見えないところでキャッシュが効いているという
事実のほうが怖い・・・。他にもトラップがありそうだなぁ。