トランザクション その9 Daoからbegin〜commit〜rollbackを呼べるようにする

Handleから自前でトランザクション制御するのは以前やりましたが、Daoでもできますのでそのサンプルです。敢えてこの方法でトランザクション処理を書く必要は無さそうですけど、一応こんなこともできますよーという意味で。

Dao015.java
public interface Dao015 extends Transactional<Dao015> {
	@SqlUpdate("insert into table001 (id, name) values (:id, :name)")
	int insert(@Bind("id") int id, @Bind("name") String name);
}
Sample024.java
private static Handle otherHandler = null;
private static Dao015 dao;

public static void main(String[] args) {
	String url = "jdbc:postgresql://192.168.52.128/jdbi";
	DBI dbi = new DBI(url, "jdbi_user", "jdbi_pass");
	dao = dbi.onDemand(Dao015.class);

	otherHandler = dbi.open();
	otherHandler.insert("truncate table table001");

	txSuccess();
	txError();

	otherHandler.close();
}

public static void txSuccess()
{
	System.out.println("[0] : count = " + countTable001()); // 0
	try {
		dao.begin();

		dao.insert(1, "name1");
		System.out.println("[1] : count = " + countTable001()); // 0
		dao.insert(2, "name2");

		dao.commit();
	} catch(Throwable e) {
		dao.rollback();
		e.printStackTrace();
	}
	System.out.println("[2] : count = " + countTable001()); // 2
}

public static void txError()
{
	System.out.println("[0] : count = " + countTable001()); // 2
	try {
		dao.begin();

		dao.insert(3, "name3");
		System.out.println("[1] : count = " + countTable001()); // 2
		dao.insert(3, "name4"); // エラー

		dao.commit();
	} catch(Throwable e) {
		dao.rollback();
		e.printStackTrace();
	}
	System.out.println("[2] : count = " + countTable001()); // 2
}

public static int countTable001()
{
	return otherHandler.createQuery("select count(*) from table001").map(IntegerMapper.FIRST).first();
}

特筆すべきは、Transactional をextendsしてるところだけですね。これにより、

  • begin
  • commit
  • rollback

を呼べるようになります。他にもいくつか便利メソッドがインジェクションされますので、org.skife.jdbi.v2.sqlobject.mixins.Transactional を見てください。
1つ注意点として、close メソッドは単にDao内に close を定義すればよかったですが、トランザクション関連のメソッドは Transactional インターフェイスを extends しないといけません。