2008-11-14 2 views
5

JDBC를 사용하여 트랜잭션을 처리하는 고전적인 방법은 auto-commit을 false로 설정하는 것 같습니다. 이렇게하면 새 트랜잭션이 만들어지고 커밋을 호출하면 다음 트랜잭션이 시작됩니다. 멀티 스레딩 응용 프로그램에서 각 스레드에 대해 새 연결을 여는 것이 일반적이라고 이해합니다.JDBC : 멀티 스레딩 응용 프로그램에서 연결을 공유하고 좋은 거래를 즐길 수 있습니까?

기본적으로 내 서버가 새로운 연결마다 하나의 스레드를 원활하게 생성 할 수 있도록 RMI 기반의 다중 클라이언트 서버 응용 프로그램을 작성하고 있습니다. 트랜잭션을 올바르게 처리하려면 각 스레드에 대해 새 연결을 만들어야합니까? 그러한 아키텍처의 비용이 많이 들지 않습니까?

답변

4

예, 일반적으로 각 스레드에 대해 새 연결을 만들어야합니다. 운영 체제가 스레드 실행 시간을 어떻게 제어하는지 (자신의 중요한 섹션을 정의 함에도 불구하고) 실수로 여러 스레드가 하나의 파이프를 통해 데이터를 보내려고 할 수 있습니다.

모든 네트워크 통신에도 동일하게 적용됩니다. 예를 들어 두 개의 스레드가 하나의 소켓을 HTTP 연결로 공유하려고한다면.

  • 스레드 1 스레드 2는 요청을
  • 요청을하게
  • 스레드 1은 당신의 모든 거래를 포장하는 경우 무의식적으로 스레드 2의 요청

의 응답을 읽고, 소켓에서 바이트를 읽어 중요한 섹션에서 전체 시작/커밋주기 동안 다른 스레드를 잠그면 스레드간에 데이터베이스 연결을 공유 할 수 있습니다. 하지만 JDBC 프로토콜에 대한 본래의 지식이 없으면 나는 그렇게하지 않을 것입니다.

대부분의 스레드에서 데이터베이스 연결이 자주 필요하지 않거나 전혀 필요하지 않은 경우 데이터베이스 작업을 수행 할 하나의 스레드를 지정하고 다른 스레드가 해당 스레드에 요청을 대기하게 할 수 있습니다. 이렇게하면 많은 연결의 오버 헤드를 줄일 수 있습니다. 그러나 환경에서 스레드 당 연결을 관리하는 방법을 알아야합니다 (또는 StackOverflow에서 다른 특정 질문을하십시오).

업데이트 : 대부분의 데이터베이스 브랜드는 단일 연결에서 여러 개의 동시 트랜잭션을 지원하지 않습니다.

별도의 트랜잭션 개체가 있고 연결 당 여러 트랜잭션을 시작하고 커밋 할 수 있으면 좋을 것입니다. 그러나 공급 업체는 단순히 지원하지 않습니다.

마찬가지로 JDBC 및 ODBC와 같은 표준 공급 업체 독립적 API는 트랜잭션 상태가 연결 개체의 속성 일뿐 아니라 동일한 가정을합니다.

+0

Ok ... 호기심에 의해서만 트랜잭션 정의가 JDBC에서의 연결 정의와 결합 된 이유에 대해 알고 있습니까? 나는 정말로 거래 객체를 고맙게 생각한다. – fulmicoton

+0

답변 해 주셔서 감사합니다. – fulmicoton

+1

이 대답에서 "실수로 여러 스레드가 하나의 파이프로 데이터를 보내려고 할 수 있습니다"라는 문구는 postgresql에서 분명히 잘못되었습니다. http://doc.postgresintl.com/jdbc/ch10.html을 참조하십시오. 연결은 최소한 병렬 처리가되지는 않았지만 스레드로부터 안전합니다. –

1

각 스레드에 대해 새 연결을 여는 것은 드문 습관입니다. 일반적으로 c3po 라이브러리와 같은 연결 풀을 사용합니다.

예를 들어 응용 프로그램 서버 나 Hibernate를 사용하는 경우 설명서를보고 연결 풀을 구성하는 방법을 찾을 수 있습니다.

+0

귀하의 기여에 감사드립니다. 내 경우에는 연결 풀없이 괜찮을 것입니다. 어쨌든 너무 자주 연결을 요청할 가능성이별로 없습니다. 다른 독자의 경우 : 저는 c3po가 훌륭한 라이브러리임을 확신합니다. 그러나 LGPL을 사용하는 것이 좋습니다. – fulmicoton

+0

LGPL의 문제점은 무엇입니까? 상용 응용 프로그램과 함께 사용할 수 있습니다 (약 GPL). –

1

동일한 연결 개체를 사용하여 여러 명령문 개체를 만들 수 있으며 이러한 문 개체는 다른 스레드에서 동시에 사용할 수 있습니다.JDBC에 의해 인터페이스되는 대부분의 최신 DB는 그렇게 할 수 있습니다. JDBC는 다음과 같이 동시 커서를 사용할 수 있습니다. PostgreSQL을 여기에 예외는 아닙니다, 예를 들어, 참조 :

http://doc.postgresintl.com/jdbc/ch10.html

이 그 풀에 반환 한 후 연결 만 문 객체를 생성하고, 즉에, 짧은 시간에 사용되지만, 연결 풀링을 할 수 있습니다. 이 짧은 시간 풀링은 JDBC 연결이 명령문 연산을 병렬 처리 할 때만 권장됩니다. 그렇지 않으면 정상적인 연결 풀링이 더 나은 결과를 보여줄 수 있습니다. 여하튼 스레드는 명령문 오브젝트로 계속 작업하고 나중에 닫을 수 있지만 연결은 닫을 수 없습니다.

1. Thread 1 opens statement 
3. Thread 2 opens statement 
4. Thread 1 does something   Thread 2 does something 
5. ...        ... 
6. Thread 1 closes statement  ... 
           7. Thread 2 closes statement 

위의 내용은 자동 커밋 모드에서만 작동합니다. 트랜잭션이 필요한 경우 스레드를 트랜잭션에 묶을 필요가 없습니다. 모든 트랜잭션을 따라 풀링을 분할하고 위와 같은 접근법을 사용할 수 있습니다. 그러나 이것은 소켓 연결 제한 때문에가 아니라 JDBC가 세션 ID를 트랜잭션 ID와 동일시하기 때문에 필요합니다.

잘 기억한다면 덜 단순한 디자인으로 API 및 제품이 있어야하며 여기서 세션 ID와 트랜잭션 ID는 동일하지 않습니다. 이 API에서는 트랜잭션이 일 때도 단일 데이터베이스 연결 오브젝트로 서버를 작성할 수 있습니다. 나중에이 API와 제품이 무엇인지 확인하고 알려줄 필요가 있습니다.