Database 为什么我会得到;“数据库已锁定”;?

Database 为什么我会得到;“数据库已锁定”;?,database,sqlite,Database,Sqlite,我在SQlite版本3.7.11上收到一个错误“database is locked”,这意味着在同一个数据库上发生了两个或多个不兼容的操作。 我尝试在谷歌上搜索“sqlite数据库已锁定”和“sqlite版本3中的文件锁定和并发”,但我无法找出这背后的原因 Sqlite3 API由以下函数(伪代码)封装: A.dll调用OutFunction(1); 当所有表都存在时,OutFunction()只打开x.db文件。当B.exe调用A.dll打开时,无法修改x.db。 如果CreateTable

我在SQlite版本3.7.11上收到一个错误“database is locked”,这意味着在同一个数据库上发生了两个或多个不兼容的操作。 我尝试在谷歌上搜索“sqlite数据库已锁定”和“sqlite版本3中的文件锁定和并发”,但我无法找出这背后的原因

Sqlite3 API由以下函数(伪代码)封装:

A.dll调用OutFunction(1); 当所有表都存在时,OutFunction()只打开x.db文件。当B.exe调用A.dll打开时,无法修改x.db。 如果CreateTable()被注释掉,则一切正常,可以更改x.db


有人能找到原因吗?

您确定一次只有一个程序可以访问数据库吗?SQLite可能存在并发性问题。请参阅主题中的。还有一些其他活动事务。显示
ExecSql
@GiagaWatt的实现,是的,当数据库锁定时,只有一个进程,我已经阅读了document@CL,在答案中附加它…可能还有其他一些活动事务,可能是显式的,也可能是隐式的。这可能是由于多个线程同时命中数据库,单个线程忘记适当地结束事务或完成语句,或者意外地“嵌套”事务。(我注意到上面的代码似乎不能保证在下一个语句开始之前完成准备好的语句。)
int dbClass::ExecSql(char *sql)
{
    gisLONG rtn=0;
    CHECK_PTRVAL(m_dbHandle)
        if(sql==NULL)
        {
            rtn=SQLITE_OK;
        }
        else
        {
            CloseCursor();
            rtn=local_sqlite3_prepare_v2((sqlite3 *)m_dbHandle,sql,-1,(sqlite3_stmt **)&m_pStmt,NULL);
        }

        if (rtn==SQLITE_OK)
        {
            rtn=sqlite3_step((sqlite3_stmt *)m_pStmt);
            if (rtn==SQLITE_ROW)
            {
                m_bFirst=false;
                m_curPos=1;
                rtn=1;
            }
            else if(rtn==SQLITE_DONE)
            {
                m_curPos=-1;
                rtn=1;
            }
            else
            {
                rtn=0;
            }
            return(rtn);
        }

        int errcode=sqlite3_errcode((sqlite3 *)m_dbHandle);
        errcode=sqlite3_extended_errcode((sqlite3 *)m_dbHandle);

        return (0);
}


bool TableExist(string tblName)
{
    string sql = "select name from sqlite_master where type='table' and name=";
    sql += tblName;

    ExecSql(sql);   // a function executes sql language

    return RowCount() > 0;  // counts of result by "select" sql
}

long CreateTableInner(string tblName, string fieldList)
{
    if (!TableExist())
    {
        string sql = "create table ";
        sql += tblName + fieldList;

        return ExecSql(sql);
    }
}

long CreateBlobTableInner(string tblName)
{
    if (!TableExist())
    {
        string sql = "create table ";
        sql += tblName;
        sql += "blob";
        sql += " (id INT, classname BLOB)";

        return ExecSql(sql);
    }
}

void CreateTable(short type)
{
    if (type == 1)
    {
        CreateTableInner("cache", "length INT, start INT");
        CreateTableInner("path", "name BLOB");
    }
    else if (type == 2)
    {
        CreateTableInner("dot", "id INT, name BLOB");
        CreateBlobTableInner("dot);

        CreateTableInner("line", "id INT, name BLOB");
        CreateBlobTableInner("line");
    }
}

OutFunction(short type)
{
    OpenA(fileName, type);  // it calls sqlite3_open_v2(), then do nothing
    CreateTable(type);
}