トランザクション その5
前回、複数Daoにまたがる場合のトランザクション処理をやってみましたが、あの設計だと複数人で開発した場合早晩破綻するのでもうちょっと工夫してみましょう。
登場人物は以下の3つ。
- 単純なDao。基本的にテーブルに付き1つのDaoが作られる。これには Transaction を付けない。
- Dao Factory インターフェイス。全部のDaoを CreateSqlObject 宣言する。
- トランザクション処理abstクラス。トランザクションを必要とする場合は、Factory Dao インターフェイス をimplementsして実際のトランザクション処理を記述する。規模が小さければこのファイルは1つ。規模が大きければ複数になる。
単純なDaoクラス
Table001Dao.java
public interface Table001Dao { @SqlUpdate("insert into table001 (id, name) values (:id, :name)") public abstract int insert(@Bind("id") int id, @Bind("name") String name); @SqlQuery("select count(*) from table001") public abstract int findCount(); }
Table002Dao.java
public interface Table002Dao { @SqlUpdate("insert into table002 (id, mail) values (:id, :mail)") public abstract int insert(@Bind("id") int id, @Bind("mail") String mail); @SqlQuery("select count(*) from table002") public abstract int findCount(); }
Dao Factory インターフェイス
DaoFactory.java
public interface DaoFactory { @CreateSqlObject Table001Dao createTable001Dao(); @CreateSqlObject Table002Dao createTable002Dao(); }
トランザクション処理abstクラス
TxDao.java
public abstract class TxDao implements DaoFactory { @Transaction public void txSuccessTest() { Table001Dao dao1 = createTable001Dao(); Table002Dao dao2 = createTable002Dao(); dao1.insert(1, "name1"); dao1.insert(2, "name2"); dao1.insert(3, "name3"); dao2.insert(1, "mail1@example.jp"); dao2.insert(2, "mail2@example.jp"); dao2.insert(3, "mail3@example.jp"); } @Transaction public void txErrorTest() { Table001Dao dao1 = createTable001Dao(); Table002Dao dao2 = createTable002Dao(); dao1.insert(4, "name4"); dao1.insert(5, "name5"); dao1.insert(6, "name6"); dao2.insert(4, "mail4@example.jp"); dao2.insert(4, "mail5@example.jp"); // エラー } }
Sample020.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"); TxDao dao = dbi.onDemand(TxDao.class); Table001Dao dao1 = dbi.onDemand(Table001Dao.class); Table002Dao dao2 = dbi.onDemand(Table002Dao.class); /* * commit test */ System.out.println("commit before table001 rows count = " + dao1.findCount()); // 0 System.out.println("commit before table002 rows count = " + dao2.findCount()); // 0 try { dao.txSuccessTest(); } catch(Throwable e) { e.printStackTrace(); } System.out.println("commit after table001 rows count = " + dao1.findCount()); // 3 System.out.println("commit after table002 rows count = " + dao2.findCount()); // 3 /* * rollback test */ System.out.println("rollback before table001 rows count = " + dao1.findCount()); // 3 System.out.println("rollback before table002 rows count = " + dao2.findCount()); // 3 try { dao.txErrorTest(); } catch(Throwable e) { e.printStackTrace(); } System.out.println("rollback after table001 rows count = " + dao1.findCount()); // 3 System.out.println("rollback after table002 rows count = " + dao2.findCount()); // 3 }