セーブポイントとトランザクション分離レベルをサポート

ローカルトランザクションですが、セーブポイントを使うためのAPIも作りました。

    @Test
    public void testSavepoint() throws Exception {
        LocalEmployeeDao dao = new LocalEmployeeDaoImpl();

        // トランザクションを取得
        LocalTransaction tx = AppConfig.getLocalTransaction();

        // トランザクション開始
        tx.begin();

        // 検索して更新
        LocalEmployee employee = dao.selectById(1);
        employee.employeeName = "hoge";
        dao.update(employee);

        // セーブポイントを作成
        tx.setSavepoint("save1");

        // 削除してからもういちど取得。employeeはnull
        dao.delete(employee);
        employee = dao.selectById(1);
        assertNull(employee); 

        // セーブポイントへ戻る(上で行った削除を取り消す)
        tx.rollback("save1");

        // 削除前の値を取得できる。employeeはnullじゃない!
        employee = dao.selectById(1);
        assertNotNull(employee);
        assertEquals("hoge", employee.employeeName);

        // ロールバック
        tx.rollback();
    }

ConnectionのAPIでは、setSavepointメソッドがSavepointオブジェクトを返し、rollbackするときにこのオブジェクトが必要になりますが、オブジェクトを持ちまわすのが面倒なので内部で管理するようにしました。LocalTransactionのAPIではセーブポイントを名前で指定してrollbackできます。セーブポイントに関係するAPIとしてはほかに releaseSavepoint(String) というのもあります。

ローカルトランザクションの開始時に、トランザクション分離レベルの指定もできるようにしました。

    @Test
    public void testIsolationLevel() throws Exception {
        LocalEmployeeDao dao = new LocalEmployeeDaoImpl();

        // トランザクションを取得
        LocalTransaction tx = AppConfig.getLocalTransaction();

        // トランザクション分離レベルを指定してトランザクション開始
        tx.begin(TransactionIsolationLevel.SERIALIZABLE);

        // 検索して更新
        LocalEmployee employee = dao.selectById(1);
        employee.employeeName = "hoge";
        dao.update(employee);

        // ロールバック
        tx.rollback();
    }

TransactionIsolationLevelは、Domaが提供する列挙型です。Connectionにある定数、TRANSACTION_XXXに対応しています。

ドキュメントを書いて、今日の夜か明日1.1.0をリリース予定です。