トランザクション その5

前回、複数Daoにまたがる場合のトランザクション処理をやってみましたが、あの設計だと複数人で開発した場合早晩破綻するのでもうちょっと工夫してみましょう。
登場人物は以下の3つ。

単純な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
}