如何使用c锁定然后解锁sqlite数据库?

时间:2014-11-11 12:42:53

标签: c database multithreading sqlite

我正在使用C语言的SQLite 3数据库测试this question

在一个帖子上,我正在访问一个表'audio'而在另一个线程上我将该表重命名为 dummy 并返回 audio 。但是我会在一段时间后得到以下错误

  1. 数据库已锁定来自一个帖子

  2. 无法在另一个交易中启动交易

  3. 我在某处读过使用事务锁定数据库并在提交后将其解锁。但这不会发生在这里。任何人都可以提出错误或正确的解决方案

    这是我的代码:

    #include <stdio.h>
    #include <pthread.h>
    #include <sqlite3.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    static int callback1(void *data, int argc, char **argv, char **azColName){
       int i;
       fprintf(stderr, "%s: ", (const char*)data);
    
          printf("%s = %s\n", azColName[0], argv[0] ? argv[0] : "NULL");
    
       printf("\n");
       return 0;
    }
    
    void *dbOps1 (void * name)
    {
        sqlite3 *db;
       char *zErrMsg = 0;
       int rc;
       char *sql;
       const char* data = "";
    
       /* Open database */
       rc = sqlite3_open("myDB.db", &db);
       if( rc ){
          printf("Can't open database: %s\n", sqlite3_errmsg(db));
          exit(0);
       }else{
          printf("Opened database successfully\n");
       }
    
       /* Create SQL statement */
       sql = "SELECT * from audio";
    
       /* Execute SQL statement */
       for(;;)
       {
        rc = sqlite3_exec(db, sql, callback1, (void*)data, &zErrMsg);
        if( rc != SQLITE_OK ){
           printf("SQL error: %s\n", zErrMsg);
           sqlite3_free(zErrMsg);
        }else{
           // printf("Operation done successfully\n");
        }
       }
       sqlite3_close(db);
       return 0;
    }
    
    static int callback2(void *data, int argc, char **argv, char **azColName){
       int i;
       fprintf(stderr, "%s: ", (const char*)data);
    
          printf("%s = %s\n", azColName[1], argv[1] ? argv[1] : "NULL");
    
       printf("\n");
       return 0;
    }
    
    void *dbOps2 (void * name)
    {
        sqlite3 *db;
       char *zErrMsg = 0;
       int rc;
       char *sql;
       const char* data = "";
    
       /* Open database */
       rc = sqlite3_open("myDB.db", &db);
       if( rc ){
          printf("Can't open database: %s\n", sqlite3_errmsg(db));
          exit(0);
       }else{
          printf("Opened database successfully\n");
       }
    
       /* Create SQL statement */
       sql = "Begin transaction;alter table audio rename to dummy;alter table dummy rename to audio;commit transaction;";
    
       /* Execute SQL statement */
       for(;;)
       {
        rc = sqlite3_exec(db, sql, callback2, (void*)data, &zErrMsg);
        if( rc != SQLITE_OK ){
           printf("SQL error: %s\n", zErrMsg);
           sqlite3_free(zErrMsg);
        }else{
           // printf("Operation done successfully\n");
        }
       }
       sqlite3_close(db);
       return 0;
    }
    
    int main()
    {
        pthread_t thread1,thread2;
        char * message1="Thread 1";
        char * message2="Thread 2";
    
        int iret1=pthread_create(&thread1,NULL,dbOps1,(void *)message1);
        int iret2=pthread_create(&thread2,NULL,dbOps2,(void *)message2);
    
        pthread_join(thread1,NULL);
        pthread_join(thread2,NULL);
    
        printf("Thread 1 return code :%d\n",iret1);
        printf("Thread 2 return code :%d\n",iret2);
        return 0;
    }
    

1 个答案:

答案 0 :(得分:0)

你得到&#34;数据库被锁定&#34;错误,因为您没有设置足够长的busy timeout。 (默认值为0,当然不是。)

&#34;无法在另一个交易中启动交易&#34;只是在开始第二个事务之前没有提交或回滚第一个事务的结果。 (sqlite3_exec在第一个错误处停止。)