0

我正在通过以下方式在 Web 应用程序中创建一个线程。在 Web 应用程序中创建线程可能不是正确的做法,但不幸的是,在我的应用程序中就是这样做的。

线程必须使用传递给其可运行对象的相同连接对象来调用存储过程。但是由于错误 DSRA9110E:语句已关闭,该过程没有得到执行。偶尔我也会收到“连接已关闭”。请注意,这只发生在 IBM Websphere 中,并且在 Apache Tomcat 中部署时没有问题。

线程是否有可能正在运行,即 thread.start() 在 persistReconcileRecord 方法完成之前执行。

我无法理解导致此语句/连接已关闭问题的原因。我感谢有关此问题的任何帮助。如果需要更多信息,请告诉我。

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
    }



}
4

1 回答 1

1

您的应用程序正在尝试的内容存在一些问题。首先,JDBC 编程模型不支持多线程访问连接。其次,即使它确实支持这一点,应用程序将连接句柄传递给另一个线程然后继续关闭连接的方式意味着当线程运行时,连接从它下面关闭。根据 JDBC 规范,关闭连接需要关闭其语句。因此,您看到的行为是设计使然(如果遇到前一种模式而不是后者,您可能会看到更糟糕的不可预测的错误,例如 IllegalStateException/ArrayIndexOutOfBoundsException 等等)

请注意,JDBC 确实支持对数据源的多线程访问。所以应用程序使用的正确模式是向线程提供数据源,线程可以获取自己的连接并在完成时关闭它。您还应该考虑在 Java EE 应用程序中使用更合适的线程处理方法。根据您使用的 WebSphere Application Server 版本,可能是 Java EE 并发(Java EE 7 的规范标准)或异步 Bean。

于 2017-02-17T14:19:54.187 回答