问题:sqlite3_close() == SQLITE_BUSY如何处理?
有时候我们需要去删除SQLite所生成的DB文件,但是如果这个DB文件被进程占用,则无法删除。首先我们需要去关闭这个DB,关闭时SQLite报错SQLITE_BUSY,它表明该DB正在被占用,有可能此时并没有业务使用DB,那么可能是什么原因呢?较大可能是之前使用SQLite有操作没有调用sqlite3_finalize()。
The sqlite3_finalize() function is called to delete a prepared statement.The application must finalize every prepared statement in order to avoid resource leaks. It is a grievous error for the application to try to use a prepared statement after it has been finalized.
即sqlite3_finalize() 用于释放之前的prepared语句,但是如果不调用,除了prepared语句占用内存未被释放外,并不会影响之后SQLite的使用,但是如果不释放资源,会造成资源泄漏和后面的SQLite无法close. 出现SQLITE_BUSY,首先需要做的是排查代码中是否存在没有调用sqlite3_finalize() 进行资源释放的问题。如果需要快捷的处理这一问题,可以使用下面的方式强制释放资源,然后关闭数据库。
强制关闭SQLite的方法
int rc = sqlite3_close(db);
if ( rc == SQLITE_BUSY)
{
// shouldn't happen in a good written application but let's handle it
sqlite3_stmt * stmt;
while ((stmt = sqlite3_next_stmt(db, NULL)) != NULL) {
sqlite3_finalize(stmt);
}
rc = sqlite3_close(db);
if (rc != SQLITE_OK) {
// throw this application away as it messes with CSQLiteDB object
// in another thread while closing it here
... // Your choice of how to deal with fatal error
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
intrc=sqlite3_close(db);
if(rc==SQLITE_BUSY)
{
// shouldn't happen in a good written application but let's handle it
sqlite3_stmt *stmt;
while((stmt=sqlite3_next_stmt(db,NULL))!=NULL){
sqlite3_finalize(stmt);
}
rc=sqlite3_close(db);
if(rc!=SQLITE_OK){
// throw this application away as it messes with CSQLiteDB object
// in another thread while closing it here
...// Your choice of how to deal with fatal error
}
}
这种方式只是一种强制资源释放和关闭的方法,强烈建议还是找到代码的问题,而不是采用这种规避方案。