2012-05-15 1 views
4

JBoss 6.1의 JDBC 풀에서 매우 불쾌한 누수가 있음을 발견했습니다.JBoss에서 대체 JDBC 풀 구현을 사용하는 방법

이 오류는 close 메서드를 기반으로 한 기본 문을 닫을 때 발생합니다.

명령문은 결코 반대하지
if (statements != null) { 
    for (Iterator 
     <Map.Entry<WrappedStatement, Throwable>> i=statements.entrySet().iterator(); 
     i.hasNext();) 
    { 
    Map.Entry<WrappedStatement, Throwable> entry = i.next(); 
    WrappedStatement ws= entry.getKey(); 
    if (trackStatements==BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) 
    { 
     Throwable stackTrace = entry.getValue(); 
     log.warn("Closing a statement you left open, please do your own housekeeping", 
       stackTrace); 
    } 
    try 
    { 
     ws.internalClose(); 
    } 
    catch (Throwable t) 
    { 
     log.warn("Exception trying to close statement:", t); 
    } 
    } 
} 

이지도에서 문을 제거하고,지도가 성장하고, 성장하고, 그 문은 결과를 저장하십시오 WrappedConnection 그들을 닫습니다 않지만 this처럼

는, 코드가 보인다 (적어도 JDBC 드라이버에서) 사용하고 있습니다.

누군가 JBoss의 jdbc 풀을 이보다 더 강력한 대체 구현으로 바꾸 었는지 궁금합니다. 당신의 문에 보유하지 않는 경우 메모리 누수가 크지 않을 수 있지만이에 작은 부록으로


는 코드와 행동, 결과 세트 (기본적으로 복사 및 붙여 넣기)와 동일 어떤 길이의 시간 (디자인에 의해 수영장에 사는 연결과는 다른).

+0

어떤 클래스와 버전입니까? 궁금해서. –

+0

@ChinBoon org.jboss.resource.adapter.jdbc.WrappedConnection입니다. 그 버전 6.1.0 최종에서하지만, 적어도 다시 5.0.0로 돌아가는 동일한 것으로 나타났습니다 – Yishai

+0

아마도 그것이 가능하지만 문서화 된 것 같지 않습니다. 그래서 JBoss 소스를 푸십시오;) –

답변

2

JBoss는 데이터 소스에 대한 연결 풀링을 자원 어댑터 RAR로 배포합니다. 기본적으로 deploy 폴더에는 jboss-local-jdbc.rarjboss-xa-jdbc.rar 두 가지가 있습니다. 연결 팩토리 W 랩퍼는 다음과 같이 선언됩니다. META-INF/ra.xml

따라서 옵션은 선언 된 데이터 소스에 따라 이들 자원 어댑터 중 하나 또는 둘 다를 대체하는 것입니다.그러나 구현은 JTS 및 보안 검사와의 트랜잭션에 자원 참여를 지원해야합니다.

그리 쉬운 일이 아니며 가장 먼저해야 할 일입니다.

+0

고마워요, 이것은 볼 곳의 루트에 도달합니다. 필자가 작성한 것처럼 코드를 변경했을 때이 기능이 필요하지는 않지만 JBoss 7로 업그레이드하는 것보다 약간 나빠질 것입니다. – Yishai

+0

JBoss 7이 변경 될지 확실하지 않습니다. WrappedConnection은 common/lib/jboss-common-jdbc-wrapper.jar에서 modules/org/jboss/ironjacamar/jdbcadapters/main/ironjacamar-jdbc-1.0.3.Final.jar로 옮겼습니다. JBoss 6.x 또는 7.x에서 DBCP 또는 C0P3을 연결 풀로 사용하는 것에 대한 문서는 아직 발견되지 않았습니다. –

+0

감사합니다 이브,하지만 그들은 7 (여기에 해당 클래스의 닫기 메서드에서 호출됩니다)에서 수정 한 : http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org .jboss.ironjacamar/ironjacamar-jdbc/1.0.7.Final/org/jboss/jca/adapters/jdbc/BaseWrapperManagedConnection.java # BaseWrapperManagedConnection.closeHandle % 28org.jboss.jca.adapters.jdbc.WrappedConnection % 29 – Yishai

3

기본 문을 닫지 못하면 JBoss의 풀링 누수가 발생하지 않습니다. 필자는 데이터베이스 공급 업체의 JDBC 드라이버 구현에 대한 책임이 있다고 생각합니다. 올바르게 회상했다면 오라클의 드라이버가 연결이 끊어 질 때 기본 리소스를 닫지 않았 음을 잘 알고 있습니다 (적어도 2006 년에는 사실이었습니다). 나는 그것이 고쳐 졌는지 모른다.

http://www.theserverside.com/discussions/thread.tss?thread_id=41036

책임은 항상 당신입니다.

try/catch 블록에서 개별적으로 래핑 된 finally 블록의 모든 ResultSet 및 Statement 인스턴스를 작성의 역순으로 닫는 것이 좋습니다.

그게 맞으면 동의합니다. 그러면 풀 구현 변경으로 충분하지 않습니다. 코드를 살펴보고 직접 해봐야 할 것입니다. 깨끗한 지속성 계층에서 현명하게 설계된 경우 비교적 쉽게 수행 할 수 있습니다.

죄송합니다. 이전에 코드를 읽지 않으 셨습니다. StatementMap에 넣는 이유, 특히 WeakHashMap이 아닌 이유를 알 수 없습니다. 내 충고는 모든 StatementResultSet 인스턴스를 지속성 계층 내에 단단히 묶는 것입니다. 메서드 범위에서 만들고 닫습니다. 캐싱 없음.

코드를 프로파일 링했다면 여기에 비용 절감 효과가 없다는 것을 알았을 것입니다. 그 클래스들 중 어느 것도 쓰레드에 안전하지 않으므로 그들을 매달 았을 때 좀더 심한 버그가 발생할 수 있습니다. 앱의 확장 성이 훨씬 향상됩니다.

+0

글쎄, 그것은 JDBC 스펙에 위배됩니다. 그래서 나는 엄격하게 코딩 문제라는 것에 동의하지 않습니다. 이 경우 우리는 Microsoft의 JDBC 드라이버를 사용하고 있으며 기본 JDBC 드라이버의 오작동은 관찰하지 않았습니다. – Yishai

+0

구현자가 사양을 준수하지 않는 경우 문제가 발생합니다. 필자는 마이크로 소프트가 아닌 오라클을 인용했다 : http://www.theserverside.com/discussions/thread.tss?thread_id=41036. 브루클린, 뉴욕에 외쳐라 - 나의 가장 오래된 딸이 지금 거기에 산다. – duffymo

+0

감사합니다, 브루클린은 위대합니다. 실제로 코드는 제 것이 아니라 JBoss의 구현 내용입니다. 나는 제 프로젝트의 맥락에서 사람들이 스펙을 따르지 않을 것이고 제 3 자 툴이 스펙을 따르지 않기 때문에 방어적인 프로그래밍 방식을 따르겠다고 말할 수 있다고 말하고 있습니다. . 어느 쪽이든, 다른 풀을 갖기 위해 JNDI에 다른 것을 등록하는 것과 같습니다. 다른 사람이 이미 그 문제를 해결했는지 궁금합니다. – Yishai