トランザクション その4

今度は、複数Daoにまたがる場合のトランザクション処理をやってみましょう

Dao013.java
public interface Dao013 {
	@SqlUpdate("insert into table001 (id, name) values (:id, :name)")
	int insert(@Bind("id") int id, @Bind("name") String name);
}
Dao014.java
public abstract class  Dao014 {
	@SqlUpdate("CREATE TABLE IF NOT EXISTS table002(id integer NOT NULL, mail character varying(100), PRIMARY KEY (id))")
	public abstract void createTable();

	@SqlUpdate("insert into table002 (id, mail) values (:id, :mail)")
	public abstract int insert(@Bind("id") int id, @Bind("mail") String name);

	@SqlQuery("select count(*) from table001")
	public abstract int findCountTable001();

	@SqlQuery("select count(*) from table002")
	public abstract int findCountTable002();

	@CreateSqlObject
	public abstract Dao013 createSqlObject();

	@Transaction
	public void txSuccessTest()
	{
		insert(1, "mail1@example.jp");
		insert(2, "mail2@example.jp");
		insert(3, "mail3@example.jp");

		Dao013 dao013 = createSqlObject();
		dao013.insert(1, "name1");
		dao013.insert(2, "name2");
		dao013.insert(3, "name3");
	}

	@Transaction
	public void txErrorTest()
	{
		insert(4, "mail4@example.jp");
		insert(5, "mail5@example.jp");
		insert(6, "mail6@example.jp");

		Dao013 dao013 = createSqlObject();
		dao013.insert(4, "name4");
		dao013.insert(5, "name5");
		dao013.insert(5, "name6"); // エラー
	}
}
Sample019.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");
	Dao014 dao = dbi.onDemand(Dao014.class);
	dao.createTable();

	/*
	 * commit test
	 */
	System.out.println("commit before table001 rows count = " + dao.findCountTable001()); // 0
	System.out.println("commit before table002 rows count = " + dao.findCountTable002()); // 0
	try {
		dao.txSuccessTest();
	} catch(Throwable e) {
		e.printStackTrace();
	}
	System.out.println("commit after table001 rows count = " + dao.findCountTable001()); // 3
	System.out.println("commit after table002 rows count = " + dao.findCountTable002()); // 3

	/*
	 * rollback test
	 */
	System.out.println("rollback before table001 rows count = " + dao.findCountTable001()); // 3
	System.out.println("rollback before table002 rows count = " + dao.findCountTable002()); // 3
	try {
		dao.txErrorTest();
	} catch(Throwable e) {
		e.printStackTrace();
	}
	System.out.println("rollback after table001 rows count = " + dao.findCountTable001()); // 3
	System.out.println("rollback after table002 rows count = " + dao.findCountTable002()); // 3
}

いくつか注意点を

  • メインのDaoは「Dao014」の方で、Dao014から、Dao013を呼び出しています
  • その際、CreateSqlObject アノテーションを付けたメソッドを定義する必要があります(他と同じように中身は空でJDBIが勝手にインジェクションしてくれます)
  • 後は Transaction アノテーション内で普通にDaoで定義されたメソッドを呼び出していけばOK