解决方法有:
1。使用进程或线程间的同步机制以避免同时操作;如用信号量,互斥锁等(pthread_mutex_lock,pthread_mutex_unlock),如果你的项目工程较大要求较高的话建议用此方法自行封装函数处理同步
2。使用sqlite提供的两个busy handler函数,但对于一个连接来说,只能有一个busy handle,两个函数会相互影响,设置一个的同时会清除另一个,应根据需要来选择。
int sqlite3_busy_handler(sqlite3 *, int (*)(void *, int), void *)
不注册此函数时默认回调函数为NULL,清除busy handle,申请不到锁直接返回;
函数可以定义一个回调函数,当出现数据库忙时sqlite会调用该函数进行延时并返回非0会重试本次操作,回调函数的第二个参数会被传递为此次因BUSY忙事件而调用该函数的次数,因此你完全可以自行控制多少次后(也就是延时多少后)才真正返回BUSY;
回调函数返回非0,数据库会重试当前操作,返回0则当前操作返回SQLITE_BUSY;
int sqlite3_busy_timeout(sqlite3*, int ms);
不注册此函数时默认超时等待为0,当ms<=0时,清除busy handle,申请不到锁直接返回;
定义一个毫秒数,当未到达该毫秒数时,sqlite会sleep并重试当前操作,
如果超过ms毫秒,仍然申请不到需要的锁,当前操作返回SQLITE_BUSY;
很多人用这个函数没有成功,其实只要你仔细查看sqlite的源码就会发现,
这个函数实际上注册了一个默认的sqlite3_busy_handler(sqliteDefaultBusyCallback),而这个回调函数在你的编译环境下可能使得第二个ms参数必需要大于1000且是他的整数倍才有意义,由于此默认callback函数延时较大,建议自己写回调函数然后用slite3_busy_handler注册,这样就可以自己用自己的延时函数或方法进行处理了.
附:===================================================================
static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */
int count /* Number of times table has been busy */
)
{
#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
static const u8 delays[] =
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
static const u8 totals[] =
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
sqlite3 *db = (sqlite3 *)ptr;
int timeout = db->busyTimeout;
int delay, prior;
assert( count>=0 );
if( count < NDELAY ){
delay = delays[count];
prior = totals[count];
}else{
delay = delays[NDELAY-1];
prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
}
if( prior + delay > timeout ){
delay = timeout - prior;
if( delay<=0 ) return 0;
}
sqlite3OsSleep(db->pVfs, delay*1000);
return 1;
#else
sqlite3 *db = (sqlite3 *)ptr;
int timeout = ((sqlite3 *)ptr)->busyTimeout;
if( (count+1)*1000 > timeout ){
return 0;//1000>timeout,so timeout must bigger than 1000
}
sqlite3OsSleep(db->pVfs, 1000000);//1000ms
return 1;
#endif
}
int sqlite3_busy_timeout(sqlite3 *db, int ms){
if( ms>0 ){
db->busyTimeout = ms;
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
}else{
sqlite3_busy_handler(db, 0, 0);
}
return SQLITE_OK;
}
3、解决方法二
加上一个循环判断。
while( 1 )
{
if( SQLITE_OK != sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg) )
{
if( strstr(m_sqlerr_msg, "database is locked") )
{
sleep(1);
continue;
}
break;
}
}
4、解决方法三
用信号量做PV操作
sem_p(semid,0);
sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg);
sem_v(semid,0);
上述4个方法是从别处转来。
还有一个方法,是对几个关键函数重新wrap,基本原理是,出现locked错误,sleep一段时间,再重新执行。第3个方法,实际上并不怎么严密。
分享到:
相关推荐
总结来说,SQLite的死锁问题主要源于资源竞争和事务顺序,通过理解死锁产生的原因,结合异常处理、事务设计优化、日志监控等手段,可以有效地预防和解决"database is locked"异常。在实际开发中,应当重视数据库的...
赠送jar包:sqlite-jdbc-3.15.1.jar; 赠送原API文档:sqlite-jdbc-3.15.1-javadoc.jar; 赠送源代码:sqlite-jdbc-3.15.1-sources.jar; 赠送Maven依赖信息文件:sqlite-jdbc-3.15.1.pom; 包含翻译后的API文档:...
在多线程环境下,由于并发操作不当,可能会出现“database is locked”(数据库被锁定)的错误,这通常涉及到SQLite的锁机制和事务处理。本文将深入探讨这个问题,并提供具体的解决方案。 一、SQLite锁机制 SQLite...
赠送jar包:sqlite-jdbc-3.34.0.jar; 赠送原API文档:sqlite-jdbc-3.34.0-javadoc.jar; 赠送源代码:sqlite-jdbc-3.34.0-sources.jar; 赠送Maven依赖信息文件:sqlite-jdbc-3.34.0.pom; 包含翻译后的API文档:...
通过以上策略,我们可以有效地在Android的多线程环境中管理SQLite数据库,防止“database locked”问题的发生。在实践中,应根据具体的应用场景和需求选择合适的解决方案,以保证应用的稳定性和性能。
sqlite-devel-3.7.17-8.el7.x86_64.rpm
"sqlite-autoconf-3330000.tar.gz"是SQLite3的一个特定版本(3330000)的源代码包,通常用于开发人员下载和编译以适应其项目需求或进行自定义扩展。 SQLite3的核心特性包括: 1. **无服务器模式**:与大多数数据库...
在本案例中,“sqlite-jdbc-3.31.1.zip”是一个包含SQLite JDBC驱动的压缩包,版本号为3.31.1,用于在Java环境中通过JDBC方式连接和操作加密后的SQLite数据库。 首先,我们需要了解如何在Java项目中使用sqlite-jdbc...
"sqlite-shell-win32-x86-3080200.zip" 是SQLite针对Windows 32位平台的命令行接口(shell)的压缩包,版本号为3.8.2.0。这个压缩包包含了一个名为"sqlite3.exe"的可执行文件,它是SQLite Shell,也就是SQLite的...
SQLite数据库是文档型数据库,其具备体积小移动方便等特点;以下jar包:sqlite-jdbc-3.30.1.jar文件为SQLite数据库对应的数据库驱动jar包;
本主题主要围绕“Sqlite-jdbc-3.7.2.jar”和“sqlite-jdbc-3.20.1.jar”两个Java JDBC驱动进行讨论,它们是Java连接SQLite数据库的关键组件。 Sqlite-jdbc驱动是Java开发者用来与SQLite数据库进行交互的桥梁。JDBC...
sqlite-jdbc-3.34.0.jar,支持M1芯片了,Android Studio可以正常链接手机了
"sqlite-jdbc-3.32.3.2.jar"是这个驱动程序的特定版本,它包含了用于连接SQLite数据库的必要组件。 这个版本的sqlite-jdbc驱动特别强调对信创(创新信息技术)环境的支持,这通常指的是中国自主研发的CPU架构和操作...
sqlite-jdbc-3.36.0.3.jar 最新吧2021 8月底更新
标题“sqlite-autoconf-3071000.tar.gz”指的是SQLite3的一个特定版本的源代码包,其中“sqlite-autoconf-3071000”是该版本的标识符,而“.tar.gz”表示这是一个使用gzip压缩的tar归档文件。这种格式在Linux和Unix-...
sqlite-jdbc-3.20.1.jar 连接Java和sqlite的最新驱动!
在本场景中,我们关注的是如何使用 `sqlite-jdbc-3.8.11.1.jar` 这个特定版本的驱动来实现 Java 与 SQLite 的交互。 首先,要使用 SQLite JDBC,你需要将 `sqlite-jdbc-3.8.11.1.jar` 添加到你的项目类路径中。如果...
这个“sqlite-tools-win32-x86-3360000.zip”压缩包是SQLite的Windows 32位版本工具集,版本号为3360000,包含了用于管理SQLite数据库的一系列命令行工具。 1. SQLite数据库系统: SQLite是一个自包含、无服务器、...
sqlite-autoconf-3320300 嵌入式数据库源码.编译命令:./configure --host=arm-linux(这里根据需要可以改为gcc,即省去该配置参数(删除--host),默认使用gcc) --prefix=/tmp/build
网上可以下到sqlite-shell-win32-x86: sqlite3.exe 2. 为了方便命令行执行,将sqlite3.exe放到svn 项目的主目录下,和.svn目录同级下。 3. cmd进入该目录下,执行 sqlite3 .svn/wc.db "select * from work_queue"....