본문 바로가기

Development/Android

Thread 와 Database 의 Connection 문제.

서비스 개발이 거의 막바지에 다달았습니다.
Server 쪽 개발하랴 Client 쪽 개발하랴 눈코뜰새 없이 바빴습니다만 결과물들을 보니 고생한 보람을 느낄 수 있네요.

Android Client 의 형태는 탭 view 들로 되어 있으며 전체적인 형태는 카톡을 상상하시면 됩니다.
탭들이 화면 하단에 4개 있으며 해당 탭들마다 다른 view 의 내용들을 출력해주는 방식입니다.

server 와 통신을 하면서 local database 에 데이터를 가져오고 보내주면서 그 데이터들을 Thread 로 처리하는 방식인데 client 에서 많은 thread 를 실행하다 보니 개발도중에 자꾸 여러가지 문제점들이 발생했었습니다.

가장 대표적인 문제점이 thread 의 database 사용에 따른 connection  과 lock 문제 였습니다.

thread 가 database 를 사용하기 위해서는 connection 을 가져 와야 하고 제대로 open 하고 close 해주어야지 다른 thread 에서 다시 database 를 사용하는데 지장이 없습니다.
게다가 server 와의 통신에서 약간의 delay 가 발생했을때 성질 급한 사용자가 다른 탭을 터치하면 먼저 실행했던 thread 가 database 를 잡고 있는 바람에 다른 탭의 thread 가 connectino 을 가져 오지 못하는 database locked 오류가 발생하기도 하는 등의 문제가 있었습니다.

결론적으로 thread 가 database 를 사용할때는 thread 간의 open, close 에 주의해야 하며 탭이동에 따른 타 thread 의 databsae 사용에 따른 lock 문제는 답이 없더라.. 입니다.

정확한 해답은 아니지만 제가 생각해낸 해결 방법은 아래와 같습니다.
물론 더 좋은 방법이 있을 수 있으며 그런 방법이 있으면 같이 공유 부탁드립니다.


1. database not open 오류.

한개의 activity 안에서 여러 thread 가 빈번하게 database 를 열고, 닫고 하다보니 onCreate 에서 database 를 열고 onStop 이나 onDestroy 에서 닫다 보니 가끔 문제가 발생했었습니다.
thread 간의 실행에서 타이밍이 조금만 맞지 않아도 먼저 실행된 thread 가 database 를 열고 닫아주지 않는 바람에 위의 오류가 발생했었는데 해결을 위한 가장 좋은 방법은 database 에 접근하는 모든 메소드에서 시작하면서 open 하고 종료하면서 close 하는 것입니다.
물론 코드양이 많아지고 약간 복잡해지긴 하지만 가장 확실한 방법입니다.


2. 탭간의 thread 로 인한 databaes lock 문제.

탭으로 구현한 client 는 사용자가 순간적으로 다른 탭으로 이동이 가능하기 때문에 한개의 database 를 각 탭이 공유하면 thread 간의 실행 타이밍으로 인해서 database lock 문제가 발생하기 쉽습니다.
(예를 들면, 사용자가 A 탭에서 server 쪽 데이터를 내려받는 로직을 실행했는데 시간이 오래 걸려서 기다리지 못하고 B 탭을 터치하는 경우 A탭의 thread 에 의해서 B탭의 thread 는 database 에 접근하지 못하는 database lock 오류가 발생합니다.)
local database 만을 이용하면 별 문제가 아닐 수도 있는데 server 와 통신하면서 데이터를 내려받거나 출력하는 애플리케이션일 경우에는 로직 실행시간이 오래 걸릴수 있기 때문에 아주 골치아픈 문제입니다.
이럴 경우 각 탭은 별개의 애플리케이션이라고 생각하면 됩니다.
각 애플리케이션이 각각의 database 에 접근한다고 가정한다면 각 탭의 thread 가 databasea 에 접근하고 실행하는데 서로 아무런 영향을 미치지 않습니다.
각 탭에서 사용하는 테이블들로 database 를 구성하고 그 database 들을 모두 한개의 애플리케이션에서 관리합니다.
한개의 탭에서는 여러 activitiy 들이 겹쳐서 출력되기 때문에 onStart, onStop, onResume 등의 life cycle 이 확실하게 보장되며 thread 간의 database lock 문제를 피할 수 있습니다.


3. 중복 실행 문제.

어찌 보면 가장 원초적인 문제이기도 하지만 가장 간단한 해결방법을 가지고 있는 문제이기도 합니다.
예를 들어 refresh 하는 기능에 있어서 사용자가 버튼을 터치 하고 난 뒤 로직이 완전히 끝나기 전에 다시 refresh 하면 로직에 따라서 오류가 발생할 수도 있습니다.
사용자가 버튼을 터치해서 refresh 하면 로직이 완전히 끝나기 전에는 버튼을 비활성화 처리합니다.




조금이나마 도움이 되셨기를..