淘先锋技术网

首页 1 2 3 4 5 6 7

问题: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

}

}

这种方式只是一种强制资源释放和关闭的方法,强烈建议还是找到代码的问题,而不是采用这种规避方案。