2017-02-17 2 views
0

다음과 같은 방식으로 웹 응용 프로그램에 스레드가 생성됩니다. 웹 응용 프로그램에서 스레드를 만드는 것은 옳은 일이 아니지만 불행히도 그것이 내 응용 프로그램에서 어떻게 수행되었는지입니다.DSRA9110E : Websphere의 스레드 실행() 내에서 문이 닫힙니다.

스레드는 실행 가능 개체에 전달 된 동일한 연결 개체를 사용하여 저장 프로 시저를 호출해야합니다. 그러나 오류로 인해 프로 시저가 실행되지 않습니다. DSRA9110E : 명령문이 닫힙니다. 간헐적으로 나는 또한 "Connection is closed"를 얻는다. 이 문제는 IBM Websphere에서만 발생하며 Apache Tomcat에 배포 할 때 아무런 문제가 없습니다.

스레드가 실행 중일 수 있습니다. 즉, persistReconcileRecord 메소드가 완료되기 전에 thread.start()가 실행될 수 있습니까?

이 문구/연결의 원인을 파악할 수 없으므로 폐쇄적 인 문제입니다. 이 문제와 관련하여 도움을 주셔서 감사합니다. 더 많은 정보가 필요하면 알려주세요.

public class MyServiceImpl{ 
    private ReconDAO reconDAO = new ReconDAO(); 

    public String anyMethod(String infodom,ReconModel recon){ 

     //persistReconcileRecord is a method in DAO class. 
     reconDAO.persistReconcileRecord(infodom, recon,"I"); 
     Connection connection=DBManager.getConnection(infodom); 
     WorkerThread worker=new WorkerThread(infodom,recon.getReconciliationId(),"I",connection); 
     Thread thread=new Thread(worker); 
     thread.start(); 

     JSONObject jsonObj=new JSONObject(); 
     jsonObj.put("EXIST_VALIDATION", "false"); 
     jsonObj.put("RECONCILIATION_ID", recon.getReconciliationId()); 
       return jsonObj.toString(); 

      } 

     } 

    public class ReconDAO{ 
     public void persistReconcileRecord(String infodom,ReconModel reconModel) throws Exception{ 
     try{ 
     //This method creates a new connection and inserts records into database and then closes it. 
     }catch(Exception e){ 

    }finally{ 
     closeConnection(connection); 
     closePreparedStatement(pstmt); 
    } 

    } 

public class WorkerThread implements Runnable{ 

    private String infodom; 
    private Long reconciliationId; 
    private String operation; 
    private Connection connection; 
    //A parameterized constructor to initialize all instance variables 

    public void run(){ 
     //Uses the connection object from this class and then closes it in finally block 
     //Calls a stored procedure 
    } 



} 

답변

1

응용 프로그램이 시도하는 것과 관련된 몇 가지 문제점이 있습니다. 첫째, JDBC 프로그래밍 모델은 연결에 대한 다중 스레드 액세스를 지원하지 않습니다. 둘째로, 이것을 지원 했더라도 응용 프로그램이 연결 핸들을 다른 스레드로 전달한 다음 연결을 닫는 방식으로 스레드가 실행될 때 연결이 그 아래에서 닫히는 것을 의미합니다. JDBC 스펙에 따라 연결 종료시 명령문을 닫아야합니다. 따라서보고있는 동작은 의도적으로 설계된 것입니다 (예를 들어, IllegalStateException/ArrayIndexOutOfBoundsException과 같은 예측할 수없는 오류가 더 나올 것으로 예상 할 수 있음)

JDBC는 멀티 스레드 데이터 소스에 대한 액세스. 따라서 응용 프로그램이 사용할 수있는 적절한 패턴은 스레드에 데이터 소스를 제공하는 것이며 스레드는 자체 연결을 확보하고 완료되면 닫을 수 있습니다. 또한 Java EE 응용 프로그램에서 스레딩에 대한보다 적절한 접근 방법을 고려해야합니다. 사용중인 WebSphere Application Server의 버전에 따라 Java EE 동시성 (Java EE 7의 스펙 표준) 또는 비동기식 Bean이 될 수 있습니다.

+0

"JDBC 사양에 따라 연결 종료시 해당 문을 닫아야합니다."closePreparedStatement 후에 closeConnection 메서드가 엄격하게 호출된다는 것을 의미합니까? 또한 persist 메소드가 완료되기 전에 스레드를 시작할 수 있습니다. 이것은 완전히 순차적 인 실행이 아니어야합니까? – Arunabh

+0

연결이 닫힌 후 명령문을 닫으려고하면 중복되지만 위험하지 않습니다. 문제는 하나의 스레드에서 연결이 만들어지고 다른 스레드로 연결이 전달된다는 것입니다. Worker 스레드는 main 메소드의 범위 밖에서 연결을 시도합니다. 즉, main 메소드 및/또는 호출자 등이 먼저 종료 될 수 있습니다. 이는 응용 프로그램 서버에 대한 연결 누출로 표시됩니다. 명세는 다른 스레드에서 사용되어서는 안되기 때문에 연결을 올바로 닫을 수 있습니다 (암시 적으로이 문도 마찬가지입니다). – njr

+0

고마워요. :) – Arunabh