인프런 커뮤니티 질문&답변

어니님의 프로필 이미지
어니

작성한 질문수

스프링 DB 1편 - 데이터 접근 핵심 원리

DataSource 이해

레거시 코드에서 DriverManager를 사용하는데요...

해결된 질문

작성

·

381

0

안녕하세요~

로드맵을 따라 듣다가 아직 이 강의를 볼 타임이 아닌데 ㅠㅠ

오늘 인수인계 받은 배치 애플리케이션의 소스코드를 봤는데 도무지 이해가 가지 않는 코드로 작성되어 있어 혹시나 싶은 마음에 강의를 찾아보니 있네요 ㅎㅎ

 

레거시 코드의 배치 애플리케이션에서 DriverManager, PreparedStatement, ResultSet을 사용해서 DB 처리를 하고 있습니다.

 

그런데...

서버가 기동될 때 최초 1회만 커넥션을 생성해서 close하지 않고 계속 사용합니다. 이걸로 서버 재기동전까지 계속 쿼리를 동작시킵니다. (PreparedStatement와 ResultSet는 사용하면 close 합니다.) 

 

강의를 보니 커넥션을 맺는 비용이 비싸기 때문에 이런 코드가 만들어진 것으로 추측해보는데요

 

close를 하지않는 단일 커넥션을 사용하는 것은 어떤 장단점을 가지는지 궁금합니다.

 

close를 하지 않는 단일 커넥션은 커넥션풀에 커넥션이 1개만 있는 경우와 같을까요?

배치 애플리케이션이니까 단일 커넥션으로 처리했을까요?

 * 배치의 정보를 드리자면.. 대략 수는 50개, 동시에 처리되는 것들이 보통 5개, 실행시간은 보통 5분 내외, 최대 3시간입니다.

 

이상한 코드가 맞겠죠?? 자야하는데 고민이 깊어지네요

답변 1

5

강의를 듣는 학생입니다.

커넥션을 1개로 계속 사용하면 커넥션 풀에 1개인 것과 비슷하다고 볼 수 있네요. 다만 커넥션을 일정 시간 사용하지 않으면 커넥션 타임 아웃이 발생하겠네요.

 

개인적으로 커넥션을 1개로 돌리면 배치에서 작업하는 특성에 따라 다를 수 있을 것 같네요. 

예를 들어 중복 체크하는 로직이 들어가 있어야 하는데 커넥션을 1개로 돌린다면 빠져도 될 수 있겠어요.

커넥션을 맺는 작업은 맺는 당시에만 비용이 발생하니 비용이 비싸서 1개를 사용하는 것 같진 않네요. 다른 숨은 의도가 있을 수도 있을 것 같네요.

 

보통 배치가 오래걸리면 그 시간 만큼 서비스에서 배치 결과를 늦게 보여주는 거니 저라면 커넥션을 늘리고 멀티 쓰레드를 사용하여 배치를 돌려 작업 시간을 줄일 것 같네요. 동시 처리 작업이 5개라고 하니 최소 5개는 사용할 것 같고요.

 

제 답변이 도움될진 모르갰지만 지나가다 적어봅니다.

선생님 답변도 기다려보겠습니다~

 

 

김영한님의 프로필 이미지
김영한
지식공유자

정민영님 답변 감사합니다^^

어니님의 프로필 이미지
어니
질문자

우선 댓글 달아주신 정민영님 감사합니다.

선생님이 댓글 달아주실 때 감사댓글 같이 달려고 기다리고 있었는데...

선생님도 같은 의견이신 것 같네요

다만 제 질문에 대한 답은 해결되진 않네요...

 

제가 답은 아니지만 테스트 하면서 얻었던 결과로는

close를 하지 않는 단일 커넥션을 사용하는 것을 잘못되었다. 입니다.

그렇게 생각한 이유는 시간이 지날수록 DB의 커서수가 계속 증가했고 리밋을 넘기면 커서 오류가 발생하기 때문이었어요. 결국 연결 시 비용은 절감할 수 있으나 필연적으로 오류를 초래할 수 밖에 없는 구조기 때문에 잘못되었다고 생각했습니다.

 

그럼 현 시점에서, close를 하는 단일 커넥션을 사용한다는 건 계속 getConnection과 close를 반복하며 상대적으로 큰 비용을 사용해야하니 좋은 방법은 아니고

 

커넥션풀을 사용하는 것이 더 나은 방법이라고 할 수 있겠는데

커넥션풀도 getConnection과 close하는 과정은 위와 동일한데 이것도 비용이 발생하는 게 아닌가 하는 것에 대한 고민은 getConnection은 이미 연결되어진 풀에 있는 커넥션 중 하나를 얻는 것이고, close도 실제 close보다는 active를 inactive로 변경하는 것처럼 보여요. 그러면서 기타 자원들을 돌려보내는 것처럼요

 

암튼 답변에 큰 기대를 했던 저로써는 매우 아쉽습니다...

많은 수강생들의 댓글에 일일히 답변을 해주시는 입장은 이해하지만

조금 더 친절한 답변을 해주셨으면 좋겠어요

선생님은 1:N이지만 저는 1:1이거든요...

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 어니님

답변에 큰 기대를 하셨는데, 아쉬운 마음을 남겨드려서 죄송합니다.

저는 민영님이 좋은 답변을 남겨주셔서 그 답변이 만족스러웠고, 그래서 어니님도 만족하실 만한 답변을 얻었을 것이라 생각했습니다.

우리가 서로 만나서 충분한 이야기를 할 수 있다면 이런 오해가 없겠지만, 아무래도 글과 Q&A 형식으로 짧게 쓰다보니 상대방의 의도를 충분히 파악하기는 어렵다 생각합니다.

그래서 답변이 만족스럽지 않은 경우 너무 고민하지 마시고, 이런이런 부분을 더 알려주시면 좋겠다고 남겨주시면 됩니다^^ (그래서 댓글을 계속 달 수 있는 것이니까요)

답변이 만족스럽지 않다고 하셔서 추가적으로 보충해드리자면

배치 프로그램이 커넥션을 하나만 사용하는 것은 잘못된 것이 아닙니다. 왜냐하면 배치 프로그램은 프로그램이 하나의 쓰레드로 동작하도록 만들기 때문에, 커넥션을 추가하는 것이 의미가 없습니다. (DB의 커서수 같은 이슈는 DB 상황이나 설정에 따라서 다름)

반대로 커넥션 풀을 만들어서 10개의 커넥션을 미리 확보한다면 그것도 좋은 방법은 아닙니다. 이 배치 프로그램은 1개의 커넥션만 있으면 되니까요^^

물론 배치 프로그램이 내부에서 병렬로 여러 쓰레드로 동작하게 한다면 이때는 1개 이상의 커넥션을 사용해야 겠지요? 이럴 때는 커넥션 풀이 도움이 될 것입니다.

진짜 문제는 바로 다음에서 설명한 구조적인 부분이겠지요?

"레거시 코드의 배치 애플리케이션에서 DriverManager, PreparedStatement, ResultSet을 사용해서 DB 처리를 하고 있습니다."

이런 부분을 강의에서 설명한 데이터소스로 변경하고, 커넥션을 1개만 사용하는 데이터소스 구현제를 사용하고, JdbcTemplate을 사용하도록 구조를 변경해두면 향후 변경에 유연하게 대응할 수 있겠지요?

도움이 되셨길 바래요^^

어니님의 프로필 이미지
어니
질문자

친절하게 설명해주셔서 감사합니다~

어니님의 프로필 이미지
어니

작성한 질문수

질문하기