我的问题是,如果方法“begin()”能够锁定比persistence.xml中的“timeout”配置更多的线程。
这是一个片段:
@Inject EntityManager em;
@Inject ContextControl ctxCtrl;
String fileType;
String fileName;
String hash;
BufferedReader reader = null;
public void run(File f, String fileType, String hash) throws ProcessorException, IOException{
this.fileType = fileType;
this.hash= hash;
this.fileName = f.getName();
try {
ctxCtrl.startContext(RequestScoped.class);
em.getTransaction().begin();
reader = openReader(f);
//rest of the code...
em.getTransaction().commit();
}catch (Exception e) {
logger.error(e.getMessage(), e);
try{ //for database breakdown purpose
em.getTransaction().rollback();
}catch(Exception e2){
logger.error(e2.getMessage(), e2);
throw new ProcessorException();
}
throw new ProcessorException();
}finally{
reader.close();
ctxCtrl.stopContext(RequestScoped.class);
}
“run”方法在循环内执行。该方法是串行执行的,没有可能的并发性。 现在,问题是线程在“em.getTransaction()。begin();”行中随机停止,没有异常。由于这是一个关键领域,所有应用程序都会停止,锁定永远不会释放。
我唯一能想到的是“begin()”方法以某种方式卡住,但不是以异常方式,而是以锁定方式(因为没有捕获异常)。 我无法重新创建问题,我只能说问题与文件无关。此外,这是在生产中发生的,所以除了检查一些日志
之外,我无法调试应用程序提前致谢
修改 我使用Deltaspike提供CDI。 Entitymanager它是在需要时随时注入的。它是这样创建的:
CLASS ENTITYMANAGER FACTORY PRODUCER
import java.io.FileInputStream;
import java.util.Properties;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.slf4j.Logger;
@ApplicationScoped
public class EntityManagerFactoryProducer {
@Inject Logger logger;
@Produces
@ApplicationScoped
public EntityManagerFactory create() {
Properties props = new Properties();
try {
props.load(new FileInputStream("cfg/connection.properties"));
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return Persistence.createEntityManagerFactory("scgach",props);
}
public void destroy(@Disposes EntityManagerFactory factory) {
factory.close();
}
}
CLASS ENTITYMANAGER PRODUCER
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@ApplicationScoped
public class EntityManagerProducer {
@Inject EntityManagerFactory emf;
@Produces @RequestScoped
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(@Disposes EntityManager em) {
if(em.isOpen())
em.close();
}
}