개발일기장
jdbc connection 획득을 할 때에 문제가 생기는 것에 대한 고찰. 본문
쿼츠로 batch job을 돌리는데 가끔씩 connection을 획득하지 못하고 지혼자 죽어서 그만.
sql는 금방금방 만드는데 Oracle에 대해서 정확히 몰라서 Copilot의 도움을 받기로 .......
가설1. Transaction이 엄청 긴 놈이 터지는 것으로 시작되었는데 거기서 sql session을 몇만개 수행함.
하나의 connection이 사용 할 수 있는 session 에는 제한이 있는가?
DBA한태 물어봤는데 무한대로 쏠 수 있다고 했지만 coplitot은 아니라고함
Q1.
네, 오라클 데이터베이스에서 하나의 커넥션(connection)이 수행할 수 있는 세션(session)의 개수는 제한됩니다. 이를 조정하려면 다음과 같은 방법을 사용할 수 있습니다:
- 세션 수 제한 확인:
- 다음 쿼리를 실행하여 현재 세션 및 프로세스 상태를 확인할 수 있습니다:
SELECT * FROM V$Resource_limit WHERE resource_name IN ('processes', 'sessions');
- 이 쿼리 결과에서 processes는 프로세스 수를, sessions는 세션 수를 나타냅니다.
- 다음 쿼리를 실행하여 현재 세션 및 프로세스 상태를 확인할 수 있습니다:
- 세션 수 제한 변경:
- 세션 수는 프로세스 수에 의해 결정됩니다. 일반적으로 다음 공식을 사용하여 최대 세션 수를 계산합니다:
SESSIONS = (PROCESSES * 1.1) + 5
- 따라서 processes 값을 조정하면 자동으로 sessions 값도 변경됩니다.
- 다음과 같이 processes 값을 변경할 수 있습니다:
ALTER SYSTEM SET processes = 200 SCOPE = spfile;
- 위 명령에서 200은 변경하고자 하는 프로세스 수를 나타냅니다.
- 세션 수는 프로세스 수에 의해 결정됩니다. 일반적으로 다음 공식을 사용하여 최대 세션 수를 계산합니다:
세션 및 프로세스 수를 조정하여 오라클 데이터베이스의 성능을 최적화할 수 있습니다.
Q2.
그럼 session 개수를 넘으면 connection은 강제로 종료되?
A2.
네, 오라클 데이터베이스에서 세션 개수가 최대치를 넘으면 새로운 세션이 생성되지 않습니다. 이로 인해 새로운 커넥션(connection)을 요청하면 오류가 발생하며, 연결이 거부됩니다. 기존 세션을 종료하거나 세션 수 제한을 늘리는 방법으로 이 문제를 해결할 수 있습니다12.
세션 개수를 늘리는 방법은 다음과 같습니다:
- 세션 수 제한 확인:
- 다음 쿼리를 실행하여 현재 세션 및 프로세스 상태를 확인할 수 있습니다:
SELECT * FROM V$Resource_limit WHERE resource_name IN ('processes', 'sessions');
- 이 쿼리 결과에서 processes는 프로세스 수를, sessions는 세션 수를 나타냅니다.
- 다음 쿼리를 실행하여 현재 세션 및 프로세스 상태를 확인할 수 있습니다:
- 세션 수 제한 변경:
- 세션 수는 프로세스 수에 의해 결정됩니다. 일반적으로 다음 공식을 사용하여 최대 세션 수를 계산합니다:
SESSIONS = (PROCESSES * 1.1) + 5
- 따라서 processes 값을 조정하면 자동으로 sessions 값도 변경됩니다.
- 다음과 같이 processes 값을 변경할 수 있습니다:
ALTER SYSTEM SET processes = 200 SCOPE = spfile;
- 위 명령에서 200은 변경하고자 하는 프로세스 수를 나타냅니다.
- 세션 수는 프로세스 수에 의해 결정됩니다. 일반적으로 다음 공식을 사용하여 최대 세션 수를 계산합니다:
세션 및 프로세스 수를 조정하여 오라클 데이터베이스의 성능을 최적화할 수 있습니다.
의심?
-> 더 많이 수행하는 놈이 있는걸로 아는데 그거는 왜 문제가 발생하지 않는가?
process에서 설정한 값이 있는지, 아니면 실제로 그만큼 수행되지가 않는 것인지.
가설2. 일반 transaction에는 close랑 really close를 둘 다 사용하는데 batch job에는 Exception 처리에 close만 사용
Q1.
A1.
JDBC에서 커넥션 풀을 사용할 때 close와 really close의 차이를 설명드리겠습니다.
- close 메서드:
- 일반적인 Connection 객체의 close() 메서드를 호출하면 물리적인 커넥션(데이터베이스 연결)이 닫힙니다.
- 커넥션 풀에서 반환된 논리적인 커넥션을 실제로 닫는 것이 아니라, 해당 커넥션을 풀에 반환합니다.
- 다른 클라이언트가 해당 논리적 커넥션을 재사용할 수 있도록 합니다.
- really close (실제로 닫기) 메서드:
- 커넥션 풀에서 반환된 논리적인 커넥션을 직접 물리적으로 닫는 메서드입니다.
- 이 메서드를 호출하면 해당 커넥션은 풀에서 제거되고 실제 데이터베이스 연결이 종료됩니다.
따라서 커넥션 풀을 사용할 때는 close() 메서드를 호출하여 논리적인 커넥션을 풀에 반환해야 하며, 풀이 실제 커넥션을 닫을지 재사용할지 결정합니다.
가설 1+2.
가설 1 -> " 이로 인해 새로운 커넥션(connection)을 요청하면 오류가 발생하며"
가설 2 -> Exception 발생 시 close만 하고 really close를 하지 못해서 좀비?같은 connection이 남는 경우가 발생함.
> session 제한에 가로막혀서 connection이 맛탱이가 감
>> close를 해버리고 다른 놈들은 이거를 획득하려고 줄을 섬
>>> 프로세스는 이게 죽었다고 판단을 하지 못하는 상황
A1.
Q1.
세션 제한을 넘었을 때 오라클 데이터베이스의 상태는 다음과 같이 처리됩니다:
- 세션 수 제한 초과:
- 세션 수가 최대치를 넘으면 새로운 세션을 생성할 수 없습니다.
- 새로운 커넥션 요청은 거부됩니다.
- 기존 세션 상태:
- 이미 활성화된 세션은 계속해서 작업을 수행합니다.
- 유휴 상태의 세션은 일정 시간 동안 활동이 없으면 자동으로 종료될 수 있습니다.
- 오류 메시지:
- 오라클 데이터베이스 로그에는 세션 수 초과와 관련된 오류 메시지가 기록됩니다.
따라서 세션 수를 적절히 관리하여 데이터베이스 성능을 최적화하는 것이 중요합니다.
A2.
Q2.
만약 connection을 close 메서드로 닫았을 때, 해당 커넥션은 커넥션 풀에 반환되지만 실제로 물리적인 연결은 종료되지 않습니다. 이 상태에서 다른 트랜잭션이 해당 커넥션을 획득하려고 할 때 다음과 같은 상황이 발생할 수 있습니다:
- 커넥션 풀에서 반환된 상태:
- close 메서드로 닫은 커넥션은 커넥션 풀에 반환됩니다.
- 다른 클라이언트가 해당 논리적 커넥션을 재사용할 수 있도록 합니다.
- 다른 트랜잭션의 요청:
- 다른 트랜잭션이 해당 커넥션을 획득하려고 할 때, 커넥션 풀은 해당 논리적 커넥션을 제공합니다.
- 이 상태에서 해당 커넥션은 이미 close되었으므로 실제 데이터베이스 연결은 종료되지 않았습니다.
- 문제 발생:
- 다른 트랜잭션이 해당 커넥션을 사용하려고 할 때, 이미 종료된 커넥션을 사용하게 됩니다.
- 이로 인해 예기치 않은 문제가 발생할 수 있으며, 데이터 정합성 등의 이슈가 발생할 수 있습니다.
따라서 커넥션을 really close하지 않고 close만 한 경우, 다른 트랜잭션에서 해당 커넥션을 사용하면 예상치 못한 결과가 발생할 수 있습니다.
내일 출근해서 테스트 해바야지
'잡담' 카테고리의 다른 글
공부 필요하다고 생각되는 것들 (3) | 2024.10.03 |
---|---|
시즈오카 여행 영수증 (0) | 2023.01.01 |
SQLP 떴냐 (0) | 2022.11.28 |
전공이랑 코딩했던거 다 까머긍ㅁ (0) | 2022.11.23 |
인생 (0) | 2022.10.24 |