문제

Java 서블릿에서 데이터베이스 연결을 관리하는 가장 좋은 방법은 무엇입니까?

현재는 간단히 연결을 엽니다. init() 기능을 수행한 다음 닫습니다. destroy().

그러나 데이터베이스 연결을 "영구적으로" 유지하는 것은 나쁜 일이 될 수 있다는 점이 걱정됩니다.

이것이 올바른 처리 방법입니까?그렇지 않다면 더 나은 옵션은 무엇입니까?

편집하다:좀 더 명확하게 설명하자면 다음과 같습니다.각 요청에 대해 단순히 새 연결을 열고 닫으려고 시도했지만 테스트를 통해 너무 많은 연결을 생성하여 성능 문제를 확인했습니다.

여러 요청을 통해 연결을 공유하는 데 어떤 가치가 있습니까?이 애플리케이션에 대한 요청은 거의 모두 "읽기 전용"이며 매우 빠르게 이루어집니다(요청된 데이터가 상당히 작음에도 불구하고).

도움이 되었습니까?

해결책

나는 실제로 Commons DBCP를 사용하는 것에 동의하지 않습니다. 연결 풀링을 관리하기 위해 컨테이너를 연기해야합니다.

Java Servlet을 사용하고 있기 때문에 서틀 컨테이너에서 실행되는 것을 의미합니다. 제가 익숙한 연결 풀 관리 (Java EE 사양에도 필요할 수도 있음)를 제공합니다. 컨테이너가 DBCP를 사용하는 경우 (Tomcat과 마찬가지로), 그렇지 않으면 컨테이너가 제공하는 모든 것을 사용하십시오.

다른 팁

모두가 말했듯이 연결 풀을 사용해야 합니다.왜?잘 지내?등.

귀하의 솔루션에 어떤 문제가 있습니까?

나도 한때 그것이 좋은 생각이라고 생각했기 때문에 이것을 알고 있습니다.문제는 두 가지입니다.

  1. 모든 스레드(서블릿 요청은 각각 하나의 스레드로 제공됨)는 동일한 연결을 공유합니다.따라서 요청은 한 번에 하나씩 처리됩니다.단일 브라우저에 앉아서 F5 키를 눌러도 매우 느립니다.시도 해봐:이 내용은 수준 높고 추상적으로 들리지만 경험적이고 테스트 가능합니다.
  2. 어떤 이유로든 연결이 끊어지면 init 메소드는 다시 호출되지 않습니다(서블릿의 서비스가 중단되지 않기 때문입니다).doGet이나 doPost에 try-catch를 넣어서 이 문제를 처리하려고 하지 마십시오. 그렇게 하면 지옥에 빠질 것이기 때문입니다(요청 없이 앱 서버를 작성하는 것과 같습니다).
  3. 생각과는 달리 트랜잭션 시작은 연결뿐만 아니라 스레드와 연결되므로 트랜잭션에 문제가 없습니다.내가 틀렸을 수도 있지만 어쨌든 이것은 나쁜 해결책이므로 걱정하지 마십시오.

연결 풀이 필요한 이유

연결 풀은 수많은 이점을 제공하지만 무엇보다도 다음과 같은 문제를 해결합니다.

  1. 실제 데이터베이스 연결을 만드는 데는 비용이 많이 듭니다.연결 풀에는 항상 몇 가지 추가 연결이 있으며 그 중 하나를 제공합니다.
  2. 연결이 실패하면 연결 풀은 새 연결을 여는 방법을 알고 있습니다.
  3. 매우 중요:모든 스레드는 자체 연결을 갖습니다.이는 스레딩이 다음과 같은 위치에서 처리된다는 것을 의미합니다.DB 수준에서.DB는 매우 효율적이며 동시 요청을 쉽게 처리할 수 있습니다.
  4. 다른 것(JDBC 연결 문자열의 중앙 집중화 위치 등)이 있지만 수백만 개의 기사, 책 등이 있습니다.이에

연결이 필요한 시기

서비스 위임(doPost, doGet, doDisco 등)에서 시작된 호출 스택의 어딘가에서 연결을 얻은 다음 올바른 작업을 수행하고 이를 finally 블록에 반환해야 합니다.C# 주요 설계자 친구가 언젠가 사용해야 한다고 말한 것을 언급하고 싶습니다. finally 100배 이상 차단 catch 블록.더 진실한 말은 결코 말하지 않았습니다 ...

어떤 연결 풀

당신은 서블릿에 있으므로 컨테이너가 제공하는 연결 풀을 사용해야 합니다.JNDI 코드는 연결을 얻는 방법을 제외하면 완전히 정상입니다.내가 아는 한 모든 서블릿 컨테이너에는 연결 풀이 있습니다.

위 답변에 대한 일부 의견에서는 대신 특정 연결 풀 API를 사용하도록 제안합니다.당신의 전쟁은 휴대용이어야하고 "배치해야합니다." 나는 이것이 기본적으로 틀렸다고 생각합니다.컨테이너에서 제공하는 연결 풀을 사용하는 경우 여러 시스템에 걸쳐 있는 컨테이너와 Java EE 사양이 제공하는 모든 멋진 기능에 앱을 배포할 수 있습니다.예, 컨테이너별 배포 설명자를 작성해야 하지만 그게 EE 방식입니다.

한 논평가는 특정 컨테이너 제공 연결 풀이 JDBC 드라이버와 작동하지 않는다고 언급했습니다(그는 Websphere를 언급했습니다).그것은 완전히 터무니없고 우스꽝스럽게 들리므로 아마도 사실일 것입니다.그런 일이 발생하면 "해야 할 일"을 모두 쓰레기통에 버리고 할 수 있는 모든 일을 하십시오.가끔은 그 대가로 돈을 받는 경우도 있어요 :)

나는 사용할 것이다 커먼즈 DBCP. 연결 풀을 관리하는 Apache 프로젝트입니다.

당신은 당신의 doget 또는 dopost에서 당신의 연결을 얻을 수 있습니다. 그런 다음 쿼리를 실행 한 다음 최종 블록에서 연결을 닫습니다. (con.close ()는 수영장으로 반환하면 실제로 닫히지 않습니다).

DBCP는 연결 시간 초과를 관리하고 복구 할 수 있습니다. 데이터베이스가 일정 기간 동안 내려 가면 현재 작업을 수행하는 방식은 응용 프로그램을 다시 시작해야합니다.

연결을 풀고 있습니까? 그렇지 않다면, 당신은 아마도 연결을 열고 닫는 오버 헤드를 줄여야 할 것입니다.

그것이 끝나지 않으면 John이 제안한 것처럼 연결을 필요로하는 한 오랫동안 연결하십시오.

가장 좋은 방법은 현재 Google을 통해 더 나은 참조 시트를 찾고있는 것입니다. 풀을 사용하는 것입니다.

초기화시 데이터베이스에 X 수의 SQL 연결 객체가 포함 된 풀이 생성됩니다. 이 객체를 ArrayList와 같은 목록에 저장하십시오. 이러한 각 물체에는 'Islised'를위한 개인 부울이 있으며, 마지막으로 사용되는 시간과 연결이 오래 걸립니다. 연결이 필요할 때마다 풀에서 하나를 요청합니다. 풀은 당신에게 첫 번째로 이용 가능한 연결을 제공하고, IsLeased 변수를 확인하거나, 새로운 연결을 만들거나 새로운 연결을 만들어 수영장에 추가합니다. 타임 스탬프를 설정하십시오. 연결이 완료되면 단순히 수영장으로 돌아와서 이식을 거짓으로 설정합니다.

끊임없이 연결되어 있지 않도록 데이터베이스를 연결하려면 때때로 풀을 통과하는 작업자 스레드를 만들고 마지막으로 연결된 시간을 확인할 수 있습니다. 충분히 길면 연결을 닫고 수영장에서 제거 할 수 있습니다.

이를 사용하면 이점은 연결 객체가 데이터베이스에 연결되기를 기다리는 긴 대기 시간이 없다는 것입니다. 이미 확립 된 연결은 원하는만큼 재사용 할 수 있습니다. 또한 응용 프로그램이 얼마나 바쁜지에 따라 연결 수를 설정할 수 있습니다.

필요한만큼 데이터베이스 연결을 열어야합니다. doGet/doPost 행동 양식.

풀.

또한 RAW JDBC를 수행하는 경우 연결, 준비 상태 등을 관리하는 데 도움이되는 것을 살펴볼 수 있습니다. 예를 들어 Spring의 JDBC 지원을 사용하여 "경량"요구 사항이 매우 빡빡하지 않는 한 코드를 단순화 할 것입니다. 많이- 그리고 당신은 봄의 다른 부분을 사용해야하지 않습니다.

몇 가지 예를 참조하십시오.

http://static.springframework.org/spring/docs/2.5.x/reference/jdbc.html

데이터 소스와 관련된 연결 풀이 트릭을 수행해야합니다. Servlet Request Method에서 데이터 소스에서 연결을 보류 할 수 있습니다 (doget/dopost, 등).

DBCP, C3P0 및 기타 많은 연결 풀에서 원하는 작업을 수행 할 수 있습니다. 연결을 풀링하는 동안 진술과 준비된 상태를 풀어주고 싶을 수도 있습니다. 또한 지시 한대로 무거운 환경을 읽는 경우 Ehcache와 같은 것을 사용하여 일부 결과를 캐시 할 수 있습니다.

Br,
~ a

일반적으로 요청별로 연결을 여는 것이 관리하기 더 쉽다는 것을 알게 될 것입니다.이는 서블릿의 doPost() 또는 doGet() 메소드를 의미합니다.

init()에서 열면 모든 요청에 ​​사용할 수 있으며 동시 요청이 있으면 어떻게 되나요?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top