싱글 톤 DAO 클래스의 연결 개체가 멤버 변수이고 레이스 조건이 발생하기 쉬운 레거시 코드를 다루고 있습니다.Java에서 thread-unsafe java.sql.Connection 객체를 사용할 수있는 가능성은 무엇입니까?
나는 잠재적 인 디자인 문제이지만 나는 자바의 jdbc 연결 객체를 다룰 때 생각할 수있는 여러 유형의 문제에 관심이 있다는 것을 알고있다.
package com.code.ref.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.code.ref.utils.common.DBUtil;
import com.code.ref.utils.common.PCMLLogger;
public class EventLoggerDAO {
private static EventLoggerDAO staticobj_EventLoggerDAO;
private Connection obj_ClsConnection;
private PreparedStatement obj_ClsPreparedStmt;
private EventLoggerDAO() {
try {
obj_ClsConnection = DBUtil.getConnection();
} catch (Exception e) {
PCMLLogger.logMessage(EventLoggerDAO.class, "EventLoggerDAO()", "Some problem in creating db connection:" + e);
}
}
public static synchronized EventLoggerDAO getInstance() {
if (staticobj_EventLoggerDAO == null) {
synchronized (EventLoggerDAO.class) {
if (staticobj_EventLoggerDAO == null)
staticobj_EventLoggerDAO = new EventLoggerDAO();
}
}
return staticobj_EventLoggerDAO;
}
public void addEvent(String sName, String sType, String sAction, String sModifiedBy) throws Exception {
StringBuffer sbQuery = new StringBuffer();
sbQuery.append("INSERT INTO TM_EVENT_LOG (NAME, TYPE, ACTION, MODIFIED_BY) ").append("VALUES (?, ?, ?, ?) ");
if(obj_ClsConnection == null)
obj_ClsConnection = DBUtil.getConnection();
obj_ClsPreparedStmt = obj_ClsConnection.prepareStatement(sbQuery.toString());
obj_ClsPreparedStmt.setString(1, sName);
obj_ClsPreparedStmt.setString(2, sType);
obj_ClsPreparedStmt.setString(3, sAction);
obj_ClsPreparedStmt.setString(4, sModifiedBy);
obj_ClsPreparedStmt.executeUpdate();
if (obj_ClsPreparedStmt != null) {
obj_ClsPreparedStmt.close();
obj_ClsPreparedStmt = null;
}
}
}
문제가을 관찰 :
은 때로는 테이블 TM_EVENT_LOG
정지를 삽입하고 서버 로그에서도 예외가 아니라고 발생 후
EventLoggerDAO 클래스 코드입니다.
경쟁 조건에서 다른 스레드가 보유한 연결 개체가 일관성없는 상태가 될 수 있으며 데이터를 커밋하지 못했을 것으로 생각됩니다. 연결은 연결 풀을 유지 관리하는 websphere 데이터 소스를 통해 파생됩니다.
왜 이런 일이 일어날 지 생각이나 아이디어가 있습니까?
코드 서식 지정에 Carl에게 감사드립니다. 나는 intially하지만 헛된 노력했다. – Tushu
당신은 경쟁 조건에 대해 명백하고 매우 심각한 문제를 가지고 있습니다. 관찰 된 증상을 일으키는 방법을 알아 내려고보다는 내가 아는 문제를 수정하는 것이 좋습니다. (오캄의 면도날과 그 모든 것). –
위의 코드에서 "java.sql.SQLException : ORA-01000 : maximum open cursors exceeded"오류가 발생했습니다. 내 사나운 생각에도이 객체가 연결 풀로 반환하지 않고이 연결을 유지하기를 원할지라도 SQL 문을 실행 한 후 매번 연결을 닫아야합니까? – Tushu