トランザクション その7
前回の続きです。ObjectAPI形式とFluent形式を融合させてトランザクション処理をしてみますが、やってはいけないサンプルです。
Daoのメソッドに Transaction アノテーションを付けるとどうなるかやってみます。
Sample022.java
public static void main(String[] args) { String url = "jdbc:postgresql://192.168.52.128/jdbi"; DBI dbi = new DBI(url, "jdbi_user", "jdbi_pass"); final Handle otherHandler = dbi.open(); final Handle h = dbi.open(); h.insert("truncate table table001"); System.out.println("before table001 rows count = " + countTable001(h)); // 0 try { h.inTransaction(new TransactionCallback<Void>() { @Override public Void inTransaction(Handle handle, TransactionStatus status) throws Exception { System.out.println("[0] : count = " + countTable001(otherHandler)); // 0 handle.insert("insert into table001(id,name) values(101, 'name101')"); System.out.println("[1] : count = " + countTable001(otherHandler)); // 0 handle.attach(Dao010.class).txSuccessTest(); System.out.println("[2] : count = " + countTable001(otherHandler)); // 4!! return null; } }); } catch(Throwable e) { e.printStackTrace(); // 例外発生 } System.out.println("after table001 rows count = " + countTable001(h)); // 4 h.close(); otherHandler.close(); } public static int countTable001(final Handle h) { return h.createQuery("select count(*) from table001").map(IntegerMapper.FIRST).first(); }
ソース中にコメントで書いてますが、[2] の所で既にコミットされてしまっているので行数が4となってしまってます。
そしてその後、h.inTransaction で例外が発生してcatchします。
というわけで、Handle.inTransaction 内でDaoを呼び出す場合は、Transaction アノテーションを付けたメソッドを呼び出してはいけません。