Doma 1.2.0の主な変更点

簡単に紹介します。

LocalTransactionにhasSavepointメソッドの追加

セーブポイントの存在チェックができるようになりました。
簡単なコードではセーブポイントのあるなしは自明なので役立たないと思いますが、セーブポイントの設定やロールバックに条件分岐が絡んだり、設定とロールバックを違うメソッドで行う際には便利だと思います。

        LocalTransaction tx = AppConfig.getLocalTransaction();
        try {
            tx.begin();
            ...
            tx.setSavepoint("save");
            ...
            if (tx.hasSavepoint("save")) {
                tx.rollback("save");
            }
            ...
            tx.commit();
        } finally {
            tx.rollback();
        }

ローカルトランザクションの開始や終了時のログをわかりやすく

        LocalTransaction tx = AppConfig.getLocalTransaction();
        try {
            tx.begin();

            Employee employee = new Employee();
            employee.setName("test");
            employee.setAge(50);
            employee.setSalary(new Salary(300));
            employee.setJobType(JobType.PRESIDENT);
            dao.insert(employee);

            tx.commit();
        } finally {
            tx.rollback();
        }

上記のコードを動かすと次のようなログが出力できます。

2010/03/20 15:39:37 org.seasar.doma.jdbc.tx.LocalTransaction begin
情報: [DOMA2063] ローカルトランザクション[1145892402]を開始しました。
2010/03/20 15:39:37 tutorial.dao.EmployeeDaoImpl insert
情報: ENTRY
2010/03/20 15:39:37 org.seasar.doma.jdbc.id.BuiltinSequenceIdGenerator getGeneratedId
情報: [DOMA2076] SQLログ : SQLファイル=[null],
select next value for EMPLOYEE_SEQ from information_schema.system_tables where table_name = 'SYSTEM_TABLES'
2010/03/20 15:39:37 tutorial.dao.EmployeeDaoImpl insert
情報: [DOMA2076] SQLログ : SQLファイル=[null],
insert into Employee (age, DEPARTMENT_ID, hiredate, id, insertTimestamp, JOB_TYPE, name, salary, updateTimestamp, VERSION) values (50, null, null, 100, '2010-03-20 15:39:37.444', 'PRESIDENT', 'test', 300, null, 1)
2010/03/20 15:39:37 tutorial.dao.EmployeeDaoImpl insert
情報: RETURN 1
2010/03/20 15:39:37 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2067] ローカルトランザクション[1145892402]をコミットしました。
2010/03/20 15:39:37 org.seasar.doma.jdbc.tx.LocalTransaction commit
情報: [DOMA2064] ローカルトランザクション[1145892402]を終了しました。

今回新しく、「ローカルトランザクションを終了しました。」のメッセージを出力しています。通常は、「開始しました」「コミット/ロールバックしました」の後で出力されますが、トランザクション開始中にエラーが発生した場合は、それらのメッセージなしで「開始しました」「終了しました」になります。
ログ出力はカスタマイズ可能なので、文言は適当に変更してお使いください。

DB接続のところは、はまりやすい箇所なので、できるだけ細かくわかりやすいログを出力可能なようにしています。あと、トランザクション開始後にもう一度開始したり、開始していないのにコミットしたりといった例外系もわかりやすくしています。

ローカルトランザクションのrollbackで例外をスローしない

rollbackはfinally節で実行してもらうことを想定していますが、rollbackが例外をスローするとtry説やcatch節でスローされた例外を握りつぶしてしまうので、rollbackでは例外をスローしないようにしています。

        LocalTransaction tx = AppConfig.getLocalTransaction();
        try {
            tx.begin();
            ...
            tx.commit();
        } finally {
            tx.rollback();
        }

もし、万が一rollbackの内部で実行しているConnection#rollback()が失敗したら、その例外はJdbcLoggerに渡してログ出力可能にしています。

aptで生成されるコードの出力先

わかりにくいという意見をもらったので、「よくある質問」に書いておきました。