ローカルキャッシュ
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でも
同じ動作になるみたい。
そもそも、見えないところでキャッシュが効いているという
事実のほうが怖い・・・。他にもトラップがありそうだなぁ。