sqlite3에서 동시 접속에 관련된 질문입니다!

콩수니의 이미지

안녕하세요
sqlite3를 이용해서 c프로그램을 짜고있는데요

동시접속에 관해서 이 기능안되는것인지 질문드립니다

하나의 프로그램에서는
2초마다 데이터가 수집되어 계속적으로 sqlite3 db에 저장을 합니다

그리고 또하나의 프로그램에서는 이 저장되 db중 일부를 가져다 쓰는데요

첫번째 프로그램에서 해당 db파일을 계속 열고있는 동안에는 다른 프로그램에서 접근을 할수없더군요

확실히 첫번째 프로그램이 종료가 되어야 다른 프로그램이 db를 가져다 쓸수있음을 확인했습니다

결국 동시에 db를 open을 할수없다는것인데
어떻게 해결할수있을까요?
쓰레드로 하면 해결할수있으련가요?
흠..

dgkim의 이미지

sqlite의 경우 별도의 데이터베이스 엔진을 데몬형태로 띄우는 것이 아니라, 데이터베이스 파일만 존재하고, 엔진이 아니라 API가 바로 접근하리라 생각됩니다.

락관리가 OS 파일의 락에 의존하여, 서로 다른 곳에서 접근하지 못할 것으로 추정합니다.

콩수니의 이미지

여러번 테스트해보니깐
sqlite경우 다른 dbms에 비해 경량화 하다보니
api로 접근을 해서 따로 원했던 기능은 가능하지 않는것같습니다.

대신에 멀티 쓰레드로 구성했더니 파일락을 통해서 잘 해주네요
감사합니다.

devband

rubenz의 이미지


//==================================================
// Share Cashe Mode.. 변경.
//==================================================
sqlite3_enable_shared_cache(1);
//쓰기 읽기 모두 가능하게 연다.
//==================================================
// DB Open.
//==================================================
if ( SQLITE_OK !=sqlite3_open_v2(g_szDBFileName,&g_pSQLite,SQLITE_OPEN_NOMUTEX |SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE,NULL))

//==================================================
// 읽기 전용 열기.
//==================================================
if ( SQLITE_OK !=sqlite3_open_v2(pFileName,&m_pRead,SQLITE_OPEN_READONLY,NULL))
{
return FALSE;
}
//프라그마로 읽기 전용으로 열기.==> 중복 가능 열기.
if( SQLITE_OK != sqlite3_exec(m_pRead,"PRAGMA read_uncommitted=TRUE",NULL,NULL,NULL))
{
sqlite3_close(m_pRead);
m_pRead = NULL;
return FALSE;
}

위와 같이 하면.. 쓰기는 하나 쓰레드에서만 가능 하지만, 읽기는 여러곳에서 읽을수 있습니다.
데이터 동기화 문제. 100개를 쓰는 도중 읽을 경우, 동기화가 잘 안맞을 수 있습니다.
즉, 완전히 commit 한 이후에 데이터를 열고, 이것을 읽어야 데이터 동기화가 잘 맞다는 것입니다.

쓰레드로 여려군데서 쓰기를 원한다면, 크리티컬 섹션으로 함수를 래퍼해서 실행시에 잠시만 기다리게 하는 방법과 Timeout(slite 함수)함수로 시간을 지연시켜 쓰기 모드를 획득하는 방법이 있습니다.
제 경험으로는 권하는 방법은 sqlite 함수의 래퍼 함수를 만들고, 쓰기 실행하는 함수에 크리티컬 섹션으로 잠시 기다리게 하는 것이 좋습니다.


rubenz의 이미지

SQLite를 래퍼하는 완전한 프로세스를 만들고,, IPC 나 TCP/IP통신으로 C/S를 만드는 방법입니다. ^^
그러면, 정해진 루트로만 데이터 접근이 이루어 지므로, 꽤 안정적입니다.
물론... 배보다 배꼽이 더 커질수도있습니다...

콩수니의 이미지

이런기능의 함수도있군요
사실 영문이라서 모든 함수를 하나하나 살펴보는데는 -_-내적 한계가있네요.
글을 써주신 내용이라면 동시에 여러명이 접근할경우에는 동기화에 문제가 생길수도있다는것인가요?
사실 임계여역을 만들고 하는 방법도 생각했으나
말그대로 배꼽이 더커질까 두렵네요.

devband

rubenz의 이미지

동기화 문제는 이렇습니다.

A 쓰레드가 접속해서 쓰는 도중임.
B 와 C 동시에 접속 해서 읽는 도중.


A 는 실제로 50개 썼지만, B 에게는 30만 보이고, C 에게는 40개가 보임.
A 가 모두 쓰기 를 끝내고, commit까지 한 상태에서 접속을 끊음.

D 새로 접속하여 열기함. ==> 데이터가 정상적으로 50개로 보임.

50개가 단순히 쓴 상태에서(자동 커밋이라 하더라도) B와 c에겐 데이터가 상이하게 보일수 있습니다만, D 에게는 정상으로 보입니다.

실시간 데이터가 아주 중요한 경우라면, 저런 현상이 문제가 될 수 있습니다.

덧붙이면, 다중으로 쓰기를 할때에 Begin / Commit을 쓴다면, sqlite자체가 다중 트랜젝션을 지원하지 않기 때문에 내부에서 플래그로 현재 상태를 항상 살피면서 수행 해야 합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.