Play2如何从服务层而不是操作层管理事务? [英] Play2 How to manage the transaction from the service layer instead of action layer?

查看:145
本文介绍了Play2如何从服务层而不是操作层管理事务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Play2.1.1 Java和JPA2.0与hibernate实现一起使用.

I am using Play2.1.1 Java with JPA2.0 with hibernate implementation.

通过代码而不是像下面那样使用@transactional来控制事务是正常的JPA代码样式,是否可以在Play上像下面那样工作?或如何使用JPA.withtranaction()做?我尝试过,不知道如何传递参数,我对功能代码不熟悉.多谢.请给我一些基于下面的示例代码.

to control the transaction by code instead of using @transactional like below is the normal JPA code style, Is there any way to work like below at Play? or how to use JPA.withtranaction() to do? I tried it, no idea how to pass in the parameter, I am not familiar with functional code. thanks a lot. Please give me some sample code based on below.

public  void createActorB(final String email, final String psw) throws Throwable {
    EntityManager manager = JPA.em();
    try {
        EntityTransaction ex = manager.getTransaction();
        this.dbActor.setEmail(email);
        this.dbActor.setCredential(psw);
        manager.persist(this.dbActor);
        ex.commit();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new ActorException(CODE.UNKNOWN, e);
    } finally {
        manager.close();
    }
}

现在我将下面的代码更改为从服务层开始事务,它看起来效率不高,还有其他写方法吗?谢谢

Now I change my code below to start transaction from service layer, It does not looks efficient, is there any other way to write? thanks

private void internalCreateActor(String email, String psw) throws ActorException {
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(psw))
            throw new ActorException(CODE.INVALIDE_PARAMETER);
        try {
            this.dbActor.setEmail(email);
            this.dbActor.setCredential(psw);
            this.dbActor.setCreateD(new Date());
            JPA.em().persist(this.dbActor);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new ActorException(CODE.UNKNOWN, e);
        }
    }

 public void createActor(final String email, final String psw, final String cellPhone, final Actor.TYPE type)
            throws Throwable {

        JPA.withTransaction(new Callback0() {
            @Override
            public void invoke() throws Throwable {
                internalCreateActor(email, psw, cellPhone, type);
            }
        });
    }

推荐答案

经过一段时间的研究,我编写了一种方法JPAUtil,它引用了Play提供的JPA,该方法通常可以用来实际上从实际上在任何地方的服务层控制事务. /p>

After some time research, I write a method JPAUtil referring to JPA provided by Play which can use normally to control the transaction manually from the service layer actually everywhere.

public class JPAUtil {

    static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<EntityManager>();

    /**
     * Get the EntityManager for specified persistence unit for this thread.
     */
    public static EntityManager em(String key) {
        Application app = Play.application();
        if (app == null) {
            throw new RuntimeException("No application running");
        }

        JPAPlugin jpaPlugin = app.plugin(JPAPlugin.class);
        if (jpaPlugin == null) {
            throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
        }

        EntityManager em = jpaPlugin.em(key);
        if (em == null) {
            throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
        }

        bindForCurrentThread(em);

        return em;
    }

    /**
     * Get the default EntityManager for this thread.
     */
    public static EntityManager em() {
        EntityManager em = currentEntityManager.get();
        if (em == null) {
            return em(Constants.DATASOURCEKEY);
        }
        return em;
    }

    /**
     * Bind an EntityManager to the current thread.
     */
    public static void bindForCurrentThread(EntityManager em) {
        currentEntityManager.set(em);
    }

    public static void closeEM() {
        EntityManager em = currentEntityManager.get();
        if (em != null) {
            em.close();
        }
        bindForCurrentThread(null);
    }

    public static void beginTransaction() {
        em().getTransaction().begin();
    }

    public static void commitTransaction() {
        em().getTransaction().commit();
    }

}

这篇关于Play2如何从服务层而不是操作层管理事务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆