【问题标题】:How to Lock and then Unlock sqlite database using c?如何使用c锁定然后解锁sqlite数据库?
【发布时间】:2014-11-11 21:46:01
【问题描述】:

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

在一个线程上,我正在访问一个表“音频”,而在另一个线程上,我将该表重命名为 dummy 并返回为 audio。但是一段时间后我会出现以下错误

  1. 数据库被锁定来自一个线程

  2. 无法从另一个线程开始另一个事务中的事务

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

这是我的代码:

#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;
}

【问题讨论】:

    标签: c database multithreading sqlite


    【解决方案1】:

    您收到“数据库已锁定”错误,因为您没有设置足够长的 busy timeout。 (默认值 0 肯定不是。)

    “无法在另一个事务中启动事务”只是在启动第二个事务之前未提交或回滚第一个事务的结果。 (sqlite3_exec 在第一个错误处停止。)

    【讨论】:

    • 我是 sqlite 并行处理的新手。你能建议我应该做出改变的地方吗?这真的很有帮助。
    • 创建连接后必须设置忙超时时间(sqlite3_open)。
    猜你喜欢
    • 1970-01-01
    • 2018-10-21
    • 2010-09-14
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2022-10-09
    相关资源
    最近更新 更多