Java EE 7のTransactionalアノテーションを試してみる
Java EE 7からの新機能 JTA 1.2で追加されたTransactionalアノテーションを試してみた。
まずmessageというフィールドをもった単純なEntityクラスを作成して
@Entity
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String message;
// GetterとSetterは長いので省略
}
次にデータを追加するクラスを作成するのだけれども今まで作成していたSessionBeanはこんな感じ。
@Stateless
public class TestFacade {
@PersistenceContext(unitName = "TESTPU")
private EntityManager em;
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
}
}
でも今回はこれをTransactionalを付加したCDIのクラスに修正する。
@RequestScoped
public class TestFacade {
@PersistenceContext(unitName = "TESTPU")
private EntityManager em;
@Transactional
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
}
}
TestFacadeをインジェクトしてtestメソッドを実行するともちろんデータが増える

ではデータ登録後にExceptionを発生させるように修正する
@Transactional
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
throw new Exception(); //追加
}
実行するとExceptionがスローされるがチェック例外なのでやっぱりデータは追加される。

ではExceptionではなくてRuntimeExceptionを発生させる。
@Transactional
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
throw new RuntimeException(); //変更
}
実行すると今度は非チェック例外なのでjavax.transaction.TransactionalExceptionがスローされて追加処理はロールバックされる。

ではTransactionalアノテーションのrollbackOnにExceptionクラスを指定したうえでExceptionを発生させてみる
@Transactional(rollbackOn = Exception.class)
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
throw new Exception();
}
実行するとチェック例外であってもデータはロールバックされて追加されない。エラーはもちろんTransactionalExceptionになる。

ではExceptionを継承したClassNotFoundExceptionを発生させてみる
@Transactional(rollbackOn = Exception.class)
public void test() throws Exception {
Test t = new Test();
t.setMessage("test");
em.persist(t);
throw new ClassNotFoundException();
}
実行するとバグなのか仕様なのかわからないけれど処理はロールバックされずにコミットされた。継承クラスじゃ駄目なのかな。
(バグっぽい:https://java.net/jira/browse/GLASSFISH-20533)
2015/4/26 追記:GlassFish4.1ではロールバックするように修正されていました。

基本的にはSessionBeanのトランザクション制御と大きな大差は無い感じ。今後はSessionBeanはあまり使わずにこっちがメインになるかもね。