python database is locked_sqlite遇到database is locked问题的完美解决
这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题,
分析下来原因是sqlite对数据库做修改操作时会做(文件)锁使得其它进程同一时间使用时会报该错误(也就是
SQLITE_BUSY),但如果仅是多进程或多线程查询sqlite是支持的。(也有可能是做sql开启事务查询等发生异常,数据库没有关闭,然后再去打开就锁定了)
解决方法有:
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{13-11-27 sqlite遇到database is locked问题的完美解决
www.360doc.com/content/10/1214/12/87000_77984300.shtml 2/2
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);
python database is locked_sqlite遇到database is locked问题的完美解决相关推荐
- sqlite遇到database is locked问题的完美解决
这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题, 分析下来原因是sqlite对数据库做修改操作时会做(文件)锁使得其它进程同一时间使用时会报该错误 ...
- win 10 caffe python=3.5 小白安装全过程(最详细,完美解决各种版本不兼容等问题)
由于caffe已经停止维护多年,现在安装过程中便会遇到很多版本不适应及各种报错问题,建议按照本文操作,亲测有效. 1.材料准备 ①visual studio 2015(已安装则忽略) ②caffe-w ...
- dpkg: error: dpkg status database is locked by another process 解决方法
dpkg: error: dpkg status database is locked by another process 解决方法 参考文章: (1)dpkg: error: dpkg statu ...
- Azure SQL Database (23) Azure SQL Database Dynamic Data Masking动态数据掩码
<Windows Azure Platform 系列文章目录> 我们在使用关系型数据的时候,有时候希望: - 管理员admin,可以查看到所有的数据 - 普通用户,某些敏感字段,比如信用卡 ...
- 解决 springboot 启动报错 -- Cannot determine embedded database driver class for database type NONE
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 问题描述 我只是新建一个全新的 springboot 工程,什么都没有写的情况下启动报错如题: ...
- 报错Cannot determine embedded database driver class for database type NONE解决方法
由于我不需要数据库,启动springboot报错: Cannot determine embedded database driver class for database type NONE If ...
- 我眼中的Oracle Database Software 和 Oracle Database
我眼中的Oracle Database Software 和 Oracle Database 我喜欢用微软的office软件和word文档(确切的说是:自己写的word文档,能够把这个Word文档想象 ...
- SpringBoot项目在启动时出现了Cannot determine embedded database driver class for database type NONE 错误
问题描述:SpringBoot项目在启动时出现了以下错误无法启动 Cannot determine embedded database driver class for database type N ...
- SpringBoot项目报错Cannot determine embedded database driver class for database type NONE
原因: Cannot determine embedded database driver class for database type NONE 这是因为spring boot默认会加载org.s ...
最新文章
- 【基本操作】主席数统计区间不同颜色个数
- 在UWP中自定义半边框样式的输入框
- leetcode101. 对称二叉树(两种做法)
- python多行注释符号_涨知识Python 为什么用 # 号作注释符?
- mscaffe 训练minist数据
- ebay html描述模板,ebay产品描述模板
- Sophix热修复的简单使用
- 压缩包伪装-阿里网盘禁止分享解决方案\更新日志
- 对接熊迈SDK工作记录之实时视频和云录像功能集成
- 【数据库基础笔记】3、约束和隔离
- 高精度线性恒压源设计及电路分析
- 幸福的烦恼:显卡算力太高而pytorch版本太低不支持
- 券商融资融券业务今年将适时试点
- python爬iptv直播源_GitHub - xkloveme/iptv-m3u: python 爬的直播源数据
- 使用ffmpeg从视频中提取音频文件
- 2019清华计算机考研名单,2019清华大学研究生硕士考研拟录取名单
- 【mac】取消crashx代理后上不了网
- 操作系统与网络 2019-1-26
- Filed II仿真软件的命令意义及如何实现超声平面波的仿真
- 网格合并案例:实现网页图片不规则排列的两种办法
热门文章
- 泛函分析4——希尔伯特空间
- 102.怎么学好软件工程?软件工程 = 工具 + 方法 + 过程
- thinkphp5基本的一些操作/API友好/获取请求信息(Request)/判断请求类型(GET...)/验证参数数据(Validate)/连接数据库/原生sql语句查询
- 操作系统原理:操作系统的启动 中断/异常/系统调用
- redis php扩展 linux,linux下为php安装redis扩展phpredis
- python子进程关闭fd_如果创建了multiprocessing.Pool,Python子进程wait()将失败
- 完整适配LUCI界面的Openwrt中EC20的QMI拨号
- 史密斯圆图串并联口诀_看得懂的史密斯圆图(个人总结)
- milp的matlab的案例代码_Matlab神经网络30个案例第1案例代码
- webbrowser控件 有数据 但页面空白_如何在Excel中实现可以切换不同数据系列的滚珠图?...