이상 데이터베이스 연결 잠 금
JDBC 프로 그래 밍 의 이상 한 문 제 를 어떻게 합 리 적 으로 처리 할 것 인 가 는 권위 있 는 책 들 도 만 족 스 러 운 답 을 내 놓 지 못 하고 있다.2003 년 전자 공업 출판사 에서 출판 한 미국 컴퓨터 보전 총서 인 라 는 책 에서 주요 장 에서 데이터 베 이 스 를 닫 고 연결 하 는 것 은 모두 catch 코드 블록 에서 이 루어 졌 으 며 마지막 24 장 에서 여러 차례 의 심 스 러 운 똑 같은 코드 가 나 왔 다.
finally {
if (con != null) {
con.close();
}
if (stmt != null) {
stmt.close();
}
}
이 코드 에서자원 을 닫 을 때 순서 오류 가 발생 했 습 니 다.
(제7 판)하 권 제4 장 데이터베이스 프로 그래 밍 1 장 에서 데이터베이스 트 랜 잭 션 프로 그래 밍 에 관 한 이상 처리 코드 를 찾 을 수 없습니다.이 를 통 해 자바 계 는 JDBC 의 응용 개발 에 대해 깊이 있 는 연구 가 부족 하 다 는 것 을 알 수 있다.
여러 개의 이상 처리 에 관 한 코드 는 대부분 아래 의 구조 에 따라 이 루어 진다.
try {
} catch (SQLException e) {
} catch (IOException e) {
} catch (XXXException e) {
} finally {
}
데이터베이스 연결 사 무 를 열지 않 았 다 면 코드 는 다음 과 같 을 수 있 습 니 다.
try {
...
} catch (SQLException e) {
} catch (IOException e) {
} catch (XXXException e) {
} finally {
con.close()
}
이런 상황 에서 데이터베이스 에 자물쇠 가 생 길 가능성 은 제로 다.데이터베이스 연결 사 무 를 열 었 다 면 코드 는 다음 과 같 을 수 있 습 니 다.
try {
...
con.commit();
} catch (SQLException e) {
con.rollback();
} catch (IOException e) {
} catch (XXXException e) {
} finally {
con.close();
}
이렇게 여러 가지 이상 이 혼 합 된 코드 중 비 SQLException 이상 이 발생 하면 잠 금 이 꺼 질 가능성 이 매우 높 으 며,비 SQLException 이상 이 발생 하면 업 무 를 제출 하지 도 않 았 고 스크롤 백 도 하지 않 았 다.JDBC 는 데이터베이스 연결 을 닫 았 지만 데이터베이스 서버 에 서 는 여전히 데이터베이스 업 무 를 열 었 다.SQL Server 2000 을 사용 할 때 이 점 은 SQL Server 2000 의 기업 관리자/관리/현재 활동/잠 금/대상 등 부분 을 관찰 하여 결론 을 얻 을 수 있다.다른 데이터베이스 제품 도 비슷 한 상황 이 있 습 니까?이 코드 는 우아 해 보이 지만 건장 성 이 부족 하 다.코드 의 건장 성 을 고려 하여 코드 를 세 개의 try{}catch(XXXException e){}finally{}로 나 누 어야 합 니 다.코드 의 우아 함 을 유지 하려 면 이 코드 의 실현 디 테 일 에 많은 노력 을 기울 여야 한다.예 를 들 어 boolean 변 수 를 몇 개 더 추가 하여 코드 가 다음 단계 까지 실 행 될 수 있 는 지 를 봐 야 한다.
제 이 드 풀 은 이상 처리 에 상당 한 공 을 들 였 다.핵심 클래스 인 ProcessVO 에 서 는 DML 조작 과 관련 된 이상 이 모두 통합 되 어 SQLException 이상 을 일괄 적 으로 던 졌 다.예 를 들 어 삽입 을 실현 하 는 바 텀 핵심 코드 에서 모두 세 가지 유형의 이상 이 발생 했다.
try{
...
} catch (java.lang.ClassCastException ex) {
throw new SQLException("java.lang.ClassCastException: " + ex.getMessage(), ex.getCause());
} catch (NumberFormatException ex) {
throw new SQLException("NumberFormatException: " + ex.getMessage(), ex.getCause());
} catch (IOException ex) {
throw new SQLException("IOException: " + ex.getMessage(), ex.getCause());
} finally {
pstmt.close();
}
관련 자원 을 열 고 닫 으 면 전체 ProcessVO 의 여러 방법 에 분산 되 지만 자원 을 닫 을 때 순 서 를 엄 격 히 주의 합 니 다.데이터베이스 연결(또는 세 션),사무,Prepared Statement 대상,Statement 대상,ResultSet 대상 등 자원 에 대해 ProcessVO 에서 지 키 는 순 서 는 다음 과 같 습 니 다.
먼저 열 고,나중에 닫 고,나중에 열 고,먼저 닫 습 니 다.
ProcessVO 에서 트 랜 잭 션 제출 을 실현 하 는 코드
/**
* 。
*
* @throws SQLException
*/
public void commit() throws SQLException {
if (!con.isClosed()) {
if (!autoCommit) {
try {
con.commit();
autoCommit = true;
con.setAutoCommit(autoCommit);
failCommit = false;
con.close();
} finally {
if (failCommit) {
rollback();
}
}
}
}
}
ProcessVO 에서 트 랜 잭 션 스크롤 백 을 실현 하 는 코드
/**
* 。
*
* @throws SQLException
*/
public void rollback() throws SQLException {
if (!con.isClosed()) {
if (!this.autoCommit) {
if (failCommit) {
if (savepoint == null) {
con.rollback();
con.close();
System.out.println("[" + dt.dateTime() + "] SQLServerException. Connection is already rollback and closed .");
} else {
con.rollback(savepoint);
con.close();
System.out.println("[" + dt.dateTime() + "] SQLServerException. Connection is already rollback at " + savepoint + " point and closed .");
}
autoCommit = true;
}
}
}
}
ProcessVO 에서 데이터베이스 연결 이나 세 션 이라는 코드 를 닫 습 니 다.
/**
*
*
* @throws SQLException
*/
@Override
public void closeCon() throws SQLException {
try {
/*
* if (rs != null && !rs.isClosed()) { rs.close(); }
*
* if (stmt != null && !stmt.isClosed()) { stmt.close(); }
*/
} finally {
if (con != null && !con.isClosed()) {
con.close();
}
}
}
ProcessVO 에서 종결 수비 자 모드 의 코드 를 더욱 보완 하 였 다.
/**
* , , 。 , , , 。 , 。<br/>
* 1、 ;<br/> 2、 SQLException , 。<br/>
*/
private final Object _finalizerGuardian = new Object() {
@Override
protected void finalize() throws SQLException, Throwable {
if (con != null && !con.isClosed()) {
try {
super.finalize();
} finally {
if (!autoCommit) {
if (failCommit) {
try {
if (savepoint == null) {
con.rollback();
} else {
con.rollback(savepoint);
}
System.out.println("[" + dt.dateTime() + "] Connection rollback in finalize.");
} catch (SQLException ex) {
Logger.getLogger(ProcessVO.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
} finally {
con.close();
autoCommit = true;
System.out.println("[" + dt.dateTime() + "] Connection is not autocommit, rollback and then closed in finalize.");
}
} else {
con.close();
System.out.println("[" + dt.dateTime() + "] Connection is autocommit, closed in finalize,You should close it.");
}
} else {
con.close();
System.out.println("[" + dt.dateTime() + "] Connection closed in finalize,You should close it.");
}
}
}
}
};
이 코드 들 은 SQLException 이 발생 하 는 전제 에서 트 랜 잭 션 을 열 면 트 랜 잭 션 이 다시 굴 러 가 는 지 확인 하고 세 션 을 닫 기 전에 트 랜 잭 션 을 닫 을 수 있 습 니 다.
JadePool 이 발표 되 기 전에 이상 과 업무 의 제출,스크롤 백 간 의 관련 에 대해 대량의 테스트 를 실시 하여 JadePool 의 핵심 클래스 인 ProcessVO 가 건장 하고 신뢰 할 수 있 도록 확보 했다.
여기
귀중 한 의견 을 제시 하여 제 가 JadePool 개원 프로젝트 를 더욱 잘 보완 할 수 있 도록 도와 주신 것 을 환영 합 니 다.실력 있 는 자바 일꾼 들 의 참 여 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.