高分求教一个关于EJB3的问题!
写了一个sessionbean, 用来删除大量的旧数据,由于容器管理(CONTAINER)好像不能设置timeout时间,所以采用BEAN管理,代码如下。 其中用到了UserTransaction, 但是发现一个问题: 当transaction 结束时(不论是正常结束commit, 还是异常结束rollback,)发现和数据库(postgres)的链接没有释放,也就是说连接数相当于减少了一个,这样当达到最大链接数时,数据库访问将失败,出现“sorry, too many clients”的错误。
初步调查,感觉应该是EntityManager的用法有问题。
因为
@PersistenceContext EntityManager em; 应该是属于容器管理的吧?(不太确定!) 所以改用
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
EntityManager em = emf.createEntityManager();
来取得em, 但是又出现错误说 No mapping for IWUser.
现在的问题就是如何能够释放数据库链接?
//!IWUser 是一张表的名字
代码如下:
----------------------------------------------------------------
@TransactionManagement(TransactionManagementType.BEAN)
public @Stateless class PeriodClearanceServiceBean implements PeriodClearanceService {
@PersistenceContext EntityManager em;
@Resource UserTransaction ut;
// EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
// EntityManager em = emf.createEntityManager();
protected void begin() throws Exception{
int transactionTimeOut = 7200; //2 hours
ut.setTransactionTimeout(transactionTimeOut);
if (ut.getStatus() == Status.STATUS_NO_TRANSACTION) {
ut.begin();
}
}
protected void commit() throws Exception{
if (ut != null) {
ut.commit();
}
}
protected void rollback() throws Exception{
if (ut != null) {
ut.rollback();
}
}
public void deleteExpiredUsers(UserType userType) {
try {
String queryString = "DELETE FROM IWUser user " +
"WHERE user.userType = :userType " ;
Timestamp limitDate = getOverdueDate(userType);
if (limitDate == null) {
return;
}
begin();
int result = em.createQuery(queryString)
.setParameter("userType", userType.getUserType())
.executeUpdate();
commit();
} catch (Exception e) {
try {
rollback();
} catch (Exception e1) {
e1.printStackTrace()
}
e.printStackTrace();
}
}
}