2017-02-17 467 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

相關問題