非同期タスクでトランザクション
【前提条件】
[環境]
- JDK 1.7.0_25
- GlassFish 4.0
- PostgreSQL 9.3
[その他]
コンテキストパスは「Sample」、ApplicationPathは「/service」。
GlassFishでJDBCリソース登録済み。
リソース名は「jdbc/blogDb」
DB・JPAのエンティティクラスなどは前回のエントリーを参照。
JavaEE7のトランザクション制御 - シュンツのつまづき日記
【タスク】
非同期で実行するタスクです。
import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.transaction.Transactional; import jp.glory.sample04.entity.AccessLog; public class TransactionTask implements Runnable{ private static int count = 0; @PersistenceContext(unitName = "BlogDb") private EntityManager manager = null; private String content = null; @Override @Transactional public void run() { count++; final AccessLog log = new AccessLog(); log.setContent(content+ " : count is " + count); manager.persist(log); executeError(); System.out.println("insert is complete"); } public void setContent(String content) { this.content = content; } private void executeError() { if ( (count % 2) == 0) { throw new RuntimeException("transaction is error."); } } }
runメソッドにTransactionalアノテーションを付与するだけです。
サンプルではinsert後、
2回ごとに例外をスローしています。
【リソースクラス】
import java.util.Date; import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedExecutorService; import javax.inject.Inject; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import jp.glory.sample04.task.TransactionTask; @Path("/tran01") public class TransasctionResource { @Inject private TransactionTask task = null; @Resource private ManagedExecutorService service = null; @POST public Response writeLog() { task.setContent("task is start in " + new Date()); service.execute(task); return Response.ok("Write log is complete.").build(); } }