play framework之事务管理

play!中持久层采用jpa,它的事务管理不需要用户进行控制:

Play will automatically manage transactions for you. It will start a transaction for each HTTP request and commit it when the HTTP response is sent. 
If your code throws an exception, the transaction will automatically rollback.

 但是只限制在它本身的一个线程内。

有时候,我们需要自己另外重起一个线程(可以理解为:不是由http请求而产生的动作)比如:定时发送邮件,而发送邮件所需要的参数配置什么的都存储在数据库中,我们需要连接数据库拿到这些配置,然后根据配置一条条去执行邮件发送。(当然原则上,如果只是读取的话,应该不需要什么事务控制,这里只是举例说明) 这时候就需要我们去手动控制事物:事物的开启,关闭,提交,回滚等。

下面是play中一个事物控制的工具类:

事物控制
package xxx.yyy.utils;

import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.PersistenceException;

import play.db.DB;
import play.db.jpa.JPA;
import play.exceptions.JPAException;

public class TransactionUtil {

/**
* 开启一个新事务
*/
public static void startTx() {
// Logger.debug("startTx for Thread: %s and waiting for new row insert for cds_conversion_queue ... ",
// Thread.currentThread());
if (JPA.local.get() != null) {
try {
JPA.local.get().entityManager.close();
} catch (Exception e) {
}
JPA.local.remove();
}
JPA jpa = new JPA();
jpa.entityManager = JPA.entityManagerFactory.createEntityManager();
jpa.entityManager.setFlushMode(FlushModeType.COMMIT);
jpa.entityManager.getTransaction().begin();
JPA.local.set(jpa);
}

public static void closeTx(boolean rollback, boolean ignoreQueue) {
// Logger.debug("closeTx(%s) for Thread: %s", rollback, Thread.currentThread());
if (JPA.local.get() == null) {
return;
}
EntityManager manager = JPA.local.get().entityManager;
try {
DB.getConnection().setAutoCommit(false);
} catch (Exception e) {
play.Logger.error(e, "Why the driver complains here?", new Object[0]);
}

if(!ignoreQueue){
manager.createNativeQuery("select queue_end()").getResultList();
}

if (manager.getTransaction().isActive()) if ((rollback) || manager.getTransaction().getRollbackOnly()) manager.getTransaction().rollback();
else try {
manager.getTransaction().commit();
} catch (Throwable e) {
for (int i = 0; i < 10; ++i) {
if ((e instanceof PersistenceException) && (e.getCause() != null)) {
e = e.getCause();
break;
}
e = e.getCause();
if (e == null) {
break;
}
}
throw new JPAException("Cannot commit", e);
}
}

/**
* 结束事务
*
*
@param rollback
*/
public static void closeTx(boolean rollback) {
closeTx(rollback, true);
}

}



posted on 2011-12-31 12:59  左手写  阅读(2956)  评论(1编辑  收藏  举报

导航