我正在以下列方式在Web应用程序中创建一个线程。在Web应用程序中创建一个线程可能不是正确的做法,但不幸的是,这是在我的应用程序中完成的。
线程必须使用传递给其runnable对象的相同连接对象来调用存储过程。但由于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
}
}
答案 0 :(得分:1)
您的应用程序尝试的内容存在一些问题。首先,JDBC编程模型不支持对连接的多线程访问。其次,即使它支持这一点,应用程序将连接句柄传递给另一个线程然后继续关闭连接的方式意味着当线程运行时,连接从它下面关闭。根据JDBC规范,关闭连接需要关闭其语句。所以你看到的行为是设计的(你可以期待看到更糟糕的不可预测的错误,如IllegalStateException / ArrayIndexOutOfBoundsException等等,如果它碰到前一个模式而不是后一个模式)
请注意,JDBC确实支持对数据源的多线程访问。因此,应用程序使用的正确模式是将数据源提供给线程,并且线程可以获得自己的连接并在完成时关闭它。您还应该考虑在Java EE应用程序中使用更合适的线程方法。根据您使用的WebSphere Application Server版本,可能是Java EE Concurrency(Java EE 7中的规范标准)或Asynchronous Beans。