2017-02-17 28 views
0

我正在以下面的方式在Web应用程序中创建一个线程。在web应用程序中创建一个线程可能不是正确的做法,但不幸的是,这是它在我的应用程序中的做法。DSRA9110E:语句在Websphere中的线程运行()内发生关闭

线程必须调用存储过程,使用传递给其可运行对象的相同连接对象。但是由于错误DSRA9110E,程序没有得到执行:语句关闭。间歇性地,我也收到“连接已关闭”。请注意,这只发生在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 Con​​currency(自Java EE 7起的规范标准)或Asynchronous Beans。

+0

“根据JDBC规范,关闭连接需要关闭它的语句。”您的意思是在closePreparedStatement之后严格调用closeConnection方法吗?在persist方法完成之前,线程也可以开始。这不应该是一个完全顺序的执行吗? – Arunabh

+0

尝试在连接关闭后关闭语句是多余的,但不应该有害。问题是连接在一个线程上创建并提供给另一个线程。 Worker线程尝试使用主方法范围之外的连接 - 这意味着主要方法和/或其调用者等可能会首先结束 - 这将显示为应用程序服务器的连接泄漏,并作为响应可能会正确地关闭连接(并隐含地声明该语句),因为按照规范,它不应该用于其他线程。 – njr

+0

非常感谢。 :) – Arunabh

相关问题