4

sqliteはWALモードで同時に同じデータベースに複数のトランザクションを持つことができますか?

これは500スレッドを生成し、各スレッドが新しいsqlite接続を作成するサンプルアプリケーションです。データの挿入はトランザクション内で行われます。

このサンプルアプリでは:


#include "sqlite3.h"
#include "nspr\prthread.h"

void CreateThreads();
static void StartThread(void *Arg);

int main()
{
    CreateThreads();
}

void CreateThreads()
{
    for(int i = 0; i<500;i++)
    {
        PR_CreateThread(PR_USER_THREAD, StartThread, NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
    }
    Sleep(10000);
}

void StartThread(void *Arg)
{
    sqlite3 *sqlite;
    char *errmsg;
    const char *err;
    const char *unused;
    int ret;
    const unsigned char * journal;
    const char *dir = "D:\\Samples\\test.sqlite";
    ret = sqlite3_open(dir, &sqlite);
    if(ret != SQLITE_OK)
    {
       err = sqlite3_errmsg(sqlite);
         return;
    }

    char query[100];
    strcpy(query, "Begin transaction");
    if(sqlite3_exec(sqlite, query, NULL,0, &errmsg) != SQLITE_OK )
    {
        printf("%s", errmsg);
        return;
    }

    strcpy(query, "insert into test values(1,2,3,4,5,6)");
    for(int i = 0; i<10;i++)
    {
        if(sqlite3_exec(sqlite, query, NULL,0, &errmsg) != SQLITE_OK )
        {
         printf("%s", errmsg);
            return;
        }
    }

    strcpy(query, "End Transaction");
    if(sqlite3_exec(sqlite, query, NULL,0, &errmsg) != SQLITE_OK )
    {
        printf("%s", errmsg);
        return;
    }
    return;
}

これを実行すると、「データベースがロックされています」というメッセージが表示されます。

私の質問は、WALモードで、同時に複数のトランザクションを実行できるかどうかです。もしそうなら、私はサンプルアプリに何が欠けていますか?

4

1 に答える 1

9

とにかく、SQLiteは現在のバージョンでは、同時書き込みをサポートしていません。複数のリーダープロセスが同時に存在する可能性がありますが、最大で1つのライターが存在します。(FAQエントリ#5を参照してください

ログ先行書き込みを有効にすると、その事実は変わりません。WALはより多くの並行性を可能にします:

WALは、リーダーがライターをブロックせず、ライターがリーダーをブロックしないため、より多くの同時実行性を提供します。読み取りと書き込みを同時に進めることができます。

ただし、並行性は記述しないでください。

ライターは、WALファイルの最後に新しいコンテンツを追加するだけです。ライターはリーダーの動作を妨げるようなことは何もしないため、ライターとリーダーは同時に実行できます。ただし、WALファイルは1つしかないため、一度に作成できるライターは1つだけです。

(上記のWALに関するドキュメントからの抜粋。)

于 2013-01-09T12:00:31.480 に答える