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はあまり使わずにこっちがメインになるかもね。