不完全解决sqlite遇到database is locked问题方法

29 篇文章 0 订阅

sqlite遇到database is locked问题的完美解决

这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题,
分析下来原因是sqlite对数据库做修改操作时会做(文件)锁使得其它进程同一时间使用时会报该错误(也就是SQLITE_BUSY),但如果仅是多进程或多线程查询sqlite是支持的。
解决方法有:
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注册,这样就可以自己用自己的延时函数或方法进行处理了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值