学Android

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 对象,这一篇就够了码字不易帮我点个赞谢谢

版权声明:本文为yuanhao-1999原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yuanhao-1999/p/11629609.html