高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了
Concurrent database access
本文译自:https://dmytrodanylyk.com/articles/concurrent-database/
对于 Android Dev 而言,有关 SQLite 的操作再经常不过了,相比你一定经历过控制台一片爆红的情况,这不禁让我们疑问:SQLite 到底是线程安全的吗?
OK 废话不多说,我们 ⬇️
直接开始
首先,假设你已经实现了一个 SQLiteHelper 类,如下所示:
public class DatabaseHelper extends SQLiteOpenHelper { ... }
现在你想要在两个子线程中,分别地向 SQLite 里写入一些数据:
// Thread 1
Context context = getApplicationContext();
DatabaseHelper helper = new DatabaseHelper(context);
SQLiteDatabase database = helper.getWritableDatabase();
database.insert(…);
database.close();
// Thread 2
Context context = getApplicationContext();
DatabaseHelper helper = new DatabaseHelper(context);
SQLiteDatabase database = helper.getWritableDatabase();
database.insert(…);
database.close();
对吧?看上去很 OK 没啥毛病。
那么这时,我们点一下 run ,gio~ 你将会在你的 logcat 里收到如下礼物「报错」:
android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)
到底是怎么回事呢?
我们分析一下报错终于发现:这是由于你每次创建 SQLiteHelper 时,都对数据库进行了一个链接操作。这时,如果你尝试着,同时从实际不同的链接中,对数据库进行写入操作,失败就是必然的了。
总结一下
如果我们想再不同的线程中,对数据库进行包括读写操作在内的任何使用,我们就必须得确保,我们使用的是同一个的连接
好,那现在问题就明了了。现在让我们创建一个单例模式类:DatabaseManager 用来创建和返回唯一的,单例 DatabaseManager 对象。
ps 有些同学问我什么是单例模式,我专门跑去写了这篇博客来解释下,单例模式-全局可用的 context 对象,这一篇就够了码字不易帮我点个赞谢谢
高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了的更多相关文章
- SQLite支持的并发访问数
SQLite objects created in a thread can only be used in that same thread.The object was created in th ...
- 「DB」数据库事务的隔离级别
*博客搬家:初版发布于 2017/04/10 00:37 原博客地址:https://my.oschina.net/sunqinwen/blog/875833 数据库事务的隔离级别 讲事务的隔离 ...
- 「Django」数据库访问优化
先做性能分析 - 两个工具 django.db.connection from django.db import connection# contextprint connection.queries ...
- (转)Spring并发访问的线程安全性问题(高度总结)
下面的记录对spring中并发的总结.理论分析参考Spring中Singleton模式的线程安全,建议先看 spring中的并发访问题: 我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下 ...
- 「笔记」AC 自动机
目录 写在前面 定义 引入 构造 暴力 字典图优化 匹配 在线 离线 复杂度 完整代码 例题 P3796 [模板]AC 自动机(加强版) P3808 [模板]AC 自动机(简单版) 「JSOI2007 ...
- 「JSOI2016」灯塔
「JSOI2016」灯塔 传送门 我们先只计算照亮左边的灯塔的最低高度,计算右边的类同,然后只要取 \(\max\) 就好了. 那么稍微整理一下式子:\(p_i \ge h_j - h_i + \sq ...
- java设计模式--解决单例设计模式中懒汉式线程安全问题
首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...
- 并发访问sqlite数据库出现databse is locked的错误的一个解决办法
作者:朱金灿 来源:http://blog.csdn.net/clever101 在并发访问sqlite数据库会出现这样一个错误:databseis locked,这是sqlite数据库对并发支持不太 ...
- Oracle 数据库中不同事务并发访问的问题
现象 以SQL/Helper为例,打开不同的SQL窗口,对同一个表格进行操作,如下所示. 窗口1:当执行更新任务.紧接着执行查询时获得一组查询结果.结果是对的. 窗口2:而在另外一个SQL查询窗口中执 ...
随机推荐
- IDEA maven使用tomcat7插件启动报错:A child container failed during start
使用maven的tomcat7插件启动项目时出现上面的错误:A child container failed during start, 出现这个问题的原因是导入了servlet-api包,与tomc ...
- Java-手动搭建SSM(Maven)
一.环境部署 操作系统:windows10专业版 jdk:1.8.0_144 IDE:eclipse-oxygen 服务器:tomcat 9.0 数据库:mysql 5.7.18 Maven:3.54 ...
- POJ-2104 K-th Number CDQ分治
题目传送门 题意:给你一个序列,长度为n,m次询问,询问一段区间的第k大. 题解:CDQ分治,对整个值域进行分治.每次取一个mid, 计算出整个区间内mid <= 的数目,如果 num > ...
- 你不得不知道的HashMap面试连环炮
为什么用HashMap? 简述一下Map类继承关系? 解决哈希冲突的方法? 为什么HashMap线程不安全? resize机制? HashMap的工作原理是什么? 有什么方法可以减少碰撞? HashM ...
- 024 实例5-身体质量指数BMI
目录 一."身体质量指数BMI"问题分析 1.1 身体质量指数BMI 1.2 问题需求 二."身体质量指数BMI"实例讲解 2.1 身体质量指标BMI 2.1. ...
- Springboot中RedisTemplate的操作
Springboot中RedisTemplate的操作 @Autowired private RedisTemplate redisTemplate; @Autowired private Strin ...
- redis之pipeline使用
redis之pipeline 我们要完成一个业务,可能会对redis做连续的多个操作,这有很多个步骤是需要依次连续执行的.这样的场景,网络传输的耗时将是限制redis处理量的主要瓶颈. 那么此时就可以 ...
- sqlserver 用户定义表类型
有时需要将内存中的表与数据库中的表比较,比如Datatable中有100行数据,需要判断在数据库中是否存在,这个时候我们就可以使用sqlserver中的[用户 定义表类型] 这里最最最重要的思路是把[ ...
- Android-隐藏app图标以及隐式启动
隐藏APP桌面图标 <activity android:name=".LaunchActivity"> <intent-filter> <action ...
- 四大组件初始之Broadcast
在进行应用设计时,需要获取很多环境参数,像电量,音量,亮度,网络等.相比较每次去询问android这些信息改变了吗.让Android告诉我们,这些信息改变了更加合理.只要这些信息改变,Android通 ...