hybrid应用的database locked问题

SQLite是库级锁,支持并发读,但是不支持并发写。所以如果多个线程同时进行写操作,就有可能造成database locked问题。如果是纯原生应用,这篇文章介绍了怎么利用FMDatabaseQueue避免锁库:

使用FMDatabaseQueue避免database locked问题

但是如果是hybrid应用,就相对比较复杂,我们的APP就踩坑了。刚开始搭框架的时候,使用cordova搭建了hybrid框架,并使用SQLitePlugin,来支持js访问数据库。然后原生的部分,就用FMDB来访问数据库

一开始的时候,大部分的数据库访问都是在js里调用的,想必这个SQLitePlugin已经处理了并发写的场景,所以一直都没有出现过锁库的情况。原生的部分,一开始没有经验,遇到了锁库的问题,后来也用FMDatabaseQueue解决了。当时大部分的操作都在js里,如果涉及到原生访问数据库的场景,一般都用模态窗阻止了用户的其他操作,所以2个sqlite的入口没有发生冲突,安稳了很长时间

但是最近需求变得更复杂,出现了js和原生代码同时操作数据库的场景,结果2个队列产生了竞争,database locked的问题又开始概率出现了

所以教训就是:如果是hybrid的应用,最好在一开始的时候就要写好数据库的公共组件,SQLitePlugin肯定是用不了了,应该是自己写一个cordova plugin,调用数据库访问的公共组件,这样无论是原生的代码,还是js代码,对数据库的操作都会被FMDatabaseQueue统一放在队列里管理,才不会出现多线程并发写的问题

对于我们这种已经踩坑的来说,只有几个办法:

1、改造,弃用SQLitePlugin

2、分析代码的调用顺序,用setTimeout等办法,尽量把调用错开

3、增加异常处理,如果由于database locked而写入失败,就等待再尝试写一次

第一种方法是最彻底的,可以从根本上解决问题,但是对于一个老项目,改造起来难度比较大,第二,三种办法实现比较简单,但是都不是彻底解决问题的办法

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。