Play2 Как управлять транзакцией из сервисного слоя вместо экшн-слоя?
Я использую Play2.1.1 Java с JPA2.0 с реализацией hibernate.
управлять транзакцией с помощью кода вместо использования @transactional, как показано ниже, - это обычный стиль кода JPA. Есть ли способ работать, как показано ниже, в Play? или как использовать JPA.withtranaction() для этого? Я попробовал, не знаю, как передать параметр, я не знаком с функциональным кодом. большое спасибо. Пожалуйста, дайте мне пример кода на основе ниже.
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();
}
}
Теперь я изменил свой код ниже, чтобы начать транзакцию с сервисного уровня. Он не выглядит эффективным, есть ли другой способ записи? Спасибо
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);
}
});
}
2 ответа
После некоторого времени исследования я пишу метод JPAUtil, ссылающийся на JPA, предоставленный Play, который обычно можно использовать для ручного управления транзакцией с сервисного уровня практически везде.
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();
}
}
Что -то вроде этого:
public static User getUserByIdentity(final AuthUserIdentity identity) {
try {
return JPA.withTransaction(new play.libs.F.Function0<User>() {
public User apply() {
return User.findByAuthUserIdentity(identity);
}
});
} catch (Throwable t) {
throw new RuntimeException(t);
}
}