非同期タスクでトランザクション

【前提条件】

[環境]
[その他]

コンテキストパスは「Sample」、ApplicationPathは「/service」。

GlassFishJDBCリソース登録済み。
リソース名は「jdbc/blogDb」

DB・JPAのエンティティクラスなどは前回のエントリーを参照。
JavaEE7のトランザクション制御 - シュンツのつまづき日記

【概要】

今回はConcurrency Utilities for JavaEE 1.0で
トランザクションの制御を行います。

【タスク】

非同期で実行するタスクです。

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();
    }
}

JAX-RSからのインジェクションは特別なことはしていません。
Injectアノテーションを付与するだけです。